Skip to content

Conversation

@ChinthakaJ98
Copy link
Contributor

@ChinthakaJ98 ChinthakaJ98 commented Dec 1, 2025

This PR will add a Manager Query view to Data Services so that queries can be created separately without creating a resource or an operation.

Screen.Recording.2025-12-02.at.09.44.29.mov

Summary by CodeRabbit

  • New Features

    • Data Service Designer split into Resource and Query Designer views with navigation and a Manage Queries action; new Query Designer UI for create/edit/delete and code highlighting.
  • UX / Validation

    • Resources and operations can reference queries; “Use Existing Query” option with conditional validation and lookup popup for selecting queries/datasources.
  • Templates

    • Added templates and actions to add/update queries and edit query references.
  • Tests

    • Updated UI tests to target the Resource Designer iframe.

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

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 1, 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

The Data Service Designer was split into resource- and query-focused views. Query support and types were added across visualizer views, forms, templates, RPC/edit flows, and syntax-tree types; queryId was propagated to resources and operations and new query CRUD flows were introduced.

Changes

Cohort / File(s) Change Summary
Types & Enums
workspaces/mi/mi-core/src/state-machine-types.ts, workspaces/common-libs/service-designer/src/definitions.ts, workspaces/mi/syntax-tree/src/syntax-tree-interfaces.ts
Added enum members DSSResourceServiceDesigner, DSSQueryServiceDesigner; added public Query interface; added queryId to DSSResource and DSSOperation; added new DSSQuery interface.
Visualizer Main & Views
workspaces/mi/mi-visualizer/src/MainPanel.tsx, workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/ResourceServiceDesigner.tsx, workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/QueryServiceDesigner.tsx, workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/MainPanelForms/index.tsx
Renamed service designer → resource designer (export/name change), added DSSQueryServiceDesigner view; MainPanel renders new enum cases; resource view title updated and "Manage Queries" button added; new QueryServiceDesigner component introduced.
Forms & SidePanels
workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/SidePanelForms/QueryForm.tsx, .../ResourceForm.tsx, .../OperationForm.tsx
Added QueryForm component and types; ResourceForm and OperationForm gain queryId and useExistingQuery, conditional validation/UI, and now accept documentUri for keylookup/popup flows; Keylookup/controller integration added.
Resource/Operation Logic & Utilities
workspaces/mi/mi-visualizer/src/utils/DSSResourceForm.ts, workspaces/mi/mi-diagram/src/components/sidePanel/dataServices/query.tsx, workspaces/mi/mi-diagram/src/components/Form/common.ts
Added query generation/mapping (generateQueryData), onQueryCreate/onQueryEdit, propagate queryId in resource/operation generation, added getQueryType; minor key/value extraction refactor; boolean/string parsing and a renaming to forceJDBCBatchRequests.
Template Engine & Constants
workspaces/mi/mi-visualizer/src/utils/template-engine/mustache-templates/core/DSS.ts, .../templateUtils.ts, workspaces/mi/mi-visualizer/src/constants/index.ts
Added query-related template generators (add-full-query, query config, SQL/expression fragments, edit-reference) and wired new template cases; added DSS_TEMPLATES keys ADD_FULL_QUERY, UPDATE_QUERY_CONFIG, UPDATE_QUERY, EDIT_QUERY_REFERENCE.
Routing, Activation & Diagram Links
workspaces/mi/mi-extension/src/project-explorer/activate.ts, workspaces/mi/mi-diagram/src/components/nodes/ReferenceNode/ReferenceNodeModel.ts, workspaces/mi/mi-visualizer/src/views/Overview/ProjectStructureView.tsx
Replaced usages of MACHINE_VIEW.DSSServiceDesigner with MACHINE_VIEW.DSSResourceServiceDesigner; command handlers and artifact mappings updated to open resource designer; reference node navigation updated.
Tests / E2E
workspaces/mi/mi-extension/src/test/e2e-playwright-tests/components/ArtifactTest/DataService.ts
Updated expected iframe labels from "Data Service Designer" → "DSS Resource Designer".
Small internal fixes
workspaces/common-libs/service-designer/src/definitions.ts, workspaces/mi/mi-diagram/src/components/Form/common.ts, workspaces/mi/mi-diagram/src/components/sidePanel/dataServices/query.tsx
Added Query interface; minor key/value extraction refactor; renamed forceJdbcBatchRequestsforceJDBCBatchRequests and adjusted parsing; removed Query ID input in one UI.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant QueryUI as Query Designer UI
    participant QueryForm
    participant RpcClient
    participant Editor as Document Editor
    participant SyntaxTree

    User->>QueryUI: Click "Add" / "Edit" Query
    QueryUI->>QueryForm: open(formData, mode)
    User->>QueryForm: submit(formData)
    QueryForm->>QueryForm: validate
    alt create
        QueryForm->>RpcClient: onQueryCreate(data, range, documentUri)
        RpcClient->>Editor: applyEdit(ADD_FULL_QUERY)
        Editor->>SyntaxTree: reparse / insert DSSQuery node
    else edit
        QueryForm->>RpcClient: onQueryEdit(data, selectedQuery, documentUri)
        RpcClient->>Editor: applyEdit(UPDATE_QUERY_CONFIG)
        RpcClient->>Editor: applyEdit(UPDATE_QUERY)
        Editor->>SyntaxTree: reparse / update DSSQuery node
    end
    Editor-->>QueryUI: document updated
    QueryUI->>SyntaxTree: refresh queries list
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

  • Areas needing extra attention:
    • workspaces/mi/mi-visualizer/src/utils/DSSResourceForm.ts (query create/edit RPC edits, isExpression detection)
    • workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/SidePanelForms/QueryForm.tsx (validation, keylookup/popup integration, documentUri usage)
    • template engine: core/DSS.ts and templateUtils.ts (new templates and conditional rendering)
    • syntax-tree changes and downstream serializers/parsers that consume queryId/DSSQuery
    • cross-module enum/name replacements to ensure no remaining references to the old DSL view name

Possibly related PRs

Suggested reviewers

  • hevayo
  • gigara
  • kanushka

"I hopped in with a nibble of code,
split the designer down a road.
Resources hold the guide,
Queries dance inside,
two snug burrows where fresh functions grow." 🐇✨

Pre-merge checks and finishing touches

❌ Failed checks (2 warnings)
Check name Status Explanation Resolution
Description check ⚠️ Warning The description is minimal and lacks critical sections required by the template such as Purpose, Goals, Approach, UI Component Development, and other mandatory sections. Complete the PR description following the provided template, including Purpose, Goals, Approach, UI/component details, test coverage, and other required sections.
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (1 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely describes the main change: adding a Manage Query view to Data Services, which is the primary objective reflected throughout the changeset.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 57d629f and 3590818.

📒 Files selected for processing (1)
  • workspaces/mi/mi-extension/src/project-explorer/activate.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • workspaces/mi/mi-extension/src/project-explorer/activate.ts

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
workspaces/mi/mi-diagram/src/components/Form/common.ts (1)

138-154: Add comments and defensive checks for special-case Query logic.

Lines 146-147 introduce special handling for key === "Query" && valueIndex == 4, accessing value[1] directly. This logic is fragile:

  1. Magic numbers: The values 4 and 1 are hardcoded without explanation
  2. No bounds checking: Accessing value[1] without verifying array length
  3. Unclear intent: Why does "Query" with valueIndex 4 need different handling?

Consider improving the code with:

  1. Add comments explaining the special case
  2. Add defensive checks for array access
  3. Consider using named constants instead of magic numbers
 const paramValues = values.map((value: any, index: number) => {
 
     if (typeof value === 'object' && value !== null) {
         const paramValues = getParamValues(value);
         const key = keyIndex != undefined && keyIndex >= 0 ? typeof value[keyIndex] === 'object' ? value[keyIndex].value : value[keyIndex] : index + 1;
+        
+        // Special handling for Query parameters where we need to extract the query name from a different position
+        let extractedValue;
+        if (key === "Query" && valueIndex === 4 && value.length > 1) {
+            extractedValue = typeof value[1] === 'object' ? value[1].value : value[1];
+        } else if (value.length > valueIndex) {
+            extractedValue = typeof value[valueIndex] === 'object' ? value[valueIndex].value : value[valueIndex];
+        }
+        
         return {
             id: index,
             key: key,
-            value: (key === "Query" && valueIndex == 4) ? (typeof value[1] === 'object' ? value[1].value : value[1]) : 
-            (typeof value[valueIndex] === 'object' ? value[valueIndex].value : value[valueIndex]),
+            value: extractedValue,
             paramValues
         };
     } else {
         return { value };
     }
 });
🧹 Nitpick comments (6)
workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/SidePanelForms/QueryForm.tsx (2)

120-126: Missing reset in useEffect dependency array.

The reset function from useForm is used inside the effect but not listed in the dependency array. While reset is generally stable, including it ensures correctness and silences exhaustive-deps warnings.

     useEffect(() => {
         if (isOpen && formData) {
             reset(formData);
         } else if (isOpen && !formData) {
             reset(newQuery);
         }
-    }, [formData, isOpen])
+    }, [formData, isOpen, reset])

128-133: Consider simplifying the submit handler.

The metaData object only contains mode, which can be directly spread into the result without an intermediate variable.

     const handleQuerySubmit = (data: QueryType) => {
-        const metaData: QueryFormData = {
-            mode: formData ? "edit" : "create"
-        };
-        onSave({ ...data, ...metaData });
+        onSave({ ...data, mode: formData ? "edit" : "create" });
     };
workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/QueryServiceDesigner.tsx (1)

130-139: Remove unused queryIndex variable.

The queryIndex variable is declared but never used in the function body.

     const openDiagram = (query: Resource) => {
-        const queryIndex = queryServiceModel.resources.findIndex((res) => res === query);
         const href = query.path;

         if (!href) {
workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/SidePanelForms/ResourceForm.tsx (1)

140-146: Missing reset in useEffect dependency array.

Similar to QueryForm, the reset function should be included in the dependency array for completeness.

     useEffect(() => {
         if (isOpen && formData) {
             reset(formData);
         } else if (isOpen && !formData) {
             reset(newResource);
         }
-    }, [formData, isOpen])
+    }, [formData, isOpen, reset])
workspaces/mi/mi-visualizer/src/utils/DSSResourceForm.ts (2)

130-151: Missing error handling in promise chain.

The getQueryType promise chain doesn't handle rejections. If getDataService fails or throws, the error will be silently swallowed.

     getQueryType(rpcClient, documentUri, data.datasource)
         .then((queryType) => {
             const queryContent = getXML(DSS_TEMPLATES.ADD_FULL_QUERY, {
                 ...formValues,
                 isExpression: queryType === "expression"
             });

             return rpcClient.getMiDiagramRpcClient().applyEdit({
                 text: queryContent,
                 documentUri,
                 range: {
                     start: {
                         line: range.end.line,
                         character: range.end.character,
                     },
                     end: {
                         line: range.end.line,
                         character: range.end.character,
                     }
                 }
             });
-        });
+        })
+        .catch((error) => {
+            console.error("Failed to create query:", error);
+        });

266-281: Consider using find instead of forEach for cleaner code.

The function iterates through all datasources even after finding a match. Using find with early return would be more efficient and idiomatic.

 async function getQueryType(rpcClient: RpcClient, documentUri: string, datasource: string): Promise<string> {
-    let queryType = "sql";
     const existingDataService = await rpcClient.getMiDiagramRpcClient().getDataService({ path: documentUri });
-    existingDataService.datasources.forEach((ds) => {
-        if (ds.dataSourceName === datasource) {
-            const propertyKeys: string[] = [];
-            ds.datasourceProperties.forEach((attr: any) => {
-                propertyKeys.push(attr.key);
-            });
-            if (propertyKeys.includes("mongoDB_servers")) {
-                queryType = "expression";
-            }
-        }
-    });
-    return queryType;
+    const ds = existingDataService.datasources.find((d) => d.dataSourceName === datasource);
+    if (ds) {
+        const hasMongoDB = ds.datasourceProperties.some((attr: any) => attr.key === "mongoDB_servers");
+        if (hasMongoDB) {
+            return "expression";
+        }
+    }
+    return "sql";
 }
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6735fb8 and 824ce36.

📒 Files selected for processing (19)
  • workspaces/common-libs/service-designer/src/definitions.ts (1 hunks)
  • workspaces/mi/mi-core/src/state-machine-types.ts (1 hunks)
  • workspaces/mi/mi-diagram/src/components/Form/common.ts (1 hunks)
  • workspaces/mi/mi-diagram/src/components/nodes/ReferenceNode/ReferenceNodeModel.ts (1 hunks)
  • workspaces/mi/mi-diagram/src/components/sidePanel/dataServices/query.tsx (3 hunks)
  • workspaces/mi/mi-extension/src/project-explorer/activate.ts (1 hunks)
  • workspaces/mi/mi-visualizer/src/MainPanel.tsx (2 hunks)
  • workspaces/mi/mi-visualizer/src/constants/index.ts (1 hunks)
  • workspaces/mi/mi-visualizer/src/utils/DSSResourceForm.ts (11 hunks)
  • workspaces/mi/mi-visualizer/src/utils/template-engine/mustache-templates/core/DSS.ts (1 hunks)
  • workspaces/mi/mi-visualizer/src/utils/template-engine/mustache-templates/templateUtils.ts (2 hunks)
  • workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/MainPanelForms/index.tsx (1 hunks)
  • workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/QueryServiceDesigner.tsx (1 hunks)
  • workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/ResourceServiceDesigner.tsx (5 hunks)
  • workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/SidePanelForms/OperationForm.tsx (5 hunks)
  • workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/SidePanelForms/QueryForm.tsx (1 hunks)
  • workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/SidePanelForms/ResourceForm.tsx (5 hunks)
  • workspaces/mi/mi-visualizer/src/views/Overview/ProjectStructureView.tsx (1 hunks)
  • workspaces/mi/syntax-tree/src/syntax-tree-interfaces.ts (1 hunks)
🧰 Additional context used
🧠 Learnings (14)
📚 Learning: 2025-11-25T06:34:10.812Z
Learnt from: CR
Repo: wso2/vscode-extensions PR: 0
File: workspaces/ballerina/component-diagram/AGENTS.md:0-0
Timestamp: 2025-11-25T06:34:10.812Z
Learning: Applies to workspaces/ballerina/component-diagram/src/components/nodes/EntryNode/components/GraphQLServiceWidget.tsx : For GraphQL services, group functions by type (Query, Subscription, Mutation) and allow independent expand/collapse of each group. Default state: Query group open, Subscription/Mutation groups collapsed

Applied to files:

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

Applied to files:

  • workspaces/mi/mi-diagram/src/components/Form/common.ts
  • workspaces/mi/mi-diagram/src/components/nodes/ReferenceNode/ReferenceNodeModel.ts
  • workspaces/mi/mi-visualizer/src/constants/index.ts
  • workspaces/mi/mi-visualizer/src/MainPanel.tsx
  • workspaces/mi/mi-visualizer/src/views/Overview/ProjectStructureView.tsx
📚 Learning: 2025-11-27T07:59:33.534Z
Learnt from: KCSAbeywickrama
Repo: wso2/vscode-extensions PR: 897
File: workspaces/ballerina/data-mapper/src/components/DataMapper/SidePanel/QueryClauses/ClausesPanel.tsx:50-59
Timestamp: 2025-11-27T07:59:33.534Z
Learning: In workspaces/ballerina/data-mapper/src/components/DataMapper/SidePanel/QueryClauses/ClausesPanel.tsx, the `clause.properties.expression` property in the `fillDefaults` function does not require defensive null/undefined checks because it's a required property enforced by form validation in ClauseEditor.

Applied to files:

  • workspaces/mi/mi-diagram/src/components/Form/common.ts
  • workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/SidePanelForms/QueryForm.tsx
  • workspaces/mi/mi-diagram/src/components/sidePanel/dataServices/query.tsx
📚 Learning: 2025-11-25T06:34:10.812Z
Learnt from: CR
Repo: wso2/vscode-extensions PR: 0
File: workspaces/ballerina/component-diagram/AGENTS.md:0-0
Timestamp: 2025-11-25T06:34:10.812Z
Learning: Applies to workspaces/ballerina/component-diagram/src/components/nodes/**/*.{ts,tsx} : Each node type must have a Model class extending NodeModel, a Factory class implementing the factory pattern, and a Widget React component for visual representation

Applied to files:

  • workspaces/mi/mi-diagram/src/components/nodes/ReferenceNode/ReferenceNodeModel.ts
📚 Learning: 2025-11-25T06:34:10.812Z
Learnt from: CR
Repo: wso2/vscode-extensions PR: 0
File: workspaces/ballerina/component-diagram/AGENTS.md:0-0
Timestamp: 2025-11-25T06:34:10.812Z
Learning: Applies to workspaces/ballerina/component-diagram/src/components/nodes/EntryNode/EntryNodeWidget.tsx : Route EntryNode rendering to specialized widgets based on service type: use AIServiceWidget for 'ai:Service', GraphQLServiceWidget for 'graphql:Service', and GeneralWidget for HTTP and other services

Applied to files:

  • workspaces/mi/mi-diagram/src/components/nodes/ReferenceNode/ReferenceNodeModel.ts
  • workspaces/mi/mi-visualizer/src/MainPanel.tsx
📚 Learning: 2025-11-25T06:34:10.812Z
Learnt from: CR
Repo: wso2/vscode-extensions PR: 0
File: workspaces/ballerina/component-diagram/AGENTS.md:0-0
Timestamp: 2025-11-25T06:34:10.812Z
Learning: Applies to workspaces/ballerina/component-diagram/src/utils/diagram.ts : Create function-level links instead of service-level links: each function should connect individually to its target connections, not the entire service

Applied to files:

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

Applied to files:

  • workspaces/mi/mi-diagram/src/components/nodes/ReferenceNode/ReferenceNodeModel.ts
📚 Learning: 2025-11-20T11:04:33.712Z
Learnt from: KCSAbeywickrama
Repo: wso2/vscode-extensions PR: 898
File: workspaces/ballerina/data-mapper/src/components/DataMapper/SidePanel/QueryClauses/ClausesPanel.tsx:38-38
Timestamp: 2025-11-20T11:04:33.712Z
Learning: In workspaces/ballerina/data-mapper/src/components/DataMapper/SidePanel/QueryClauses/ClausesPanel.tsx, the use of `useDMQueryClausesPanelStore.getState()` to access `clauseToAdd` and `setClauseToAdd` (instead of the hook subscription pattern) is intentional to prevent re-renders when these state values change.

Applied to files:

  • workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/SidePanelForms/QueryForm.tsx
  • workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/SidePanelForms/OperationForm.tsx
  • workspaces/mi/mi-diagram/src/components/sidePanel/dataServices/query.tsx
📚 Learning: 2025-11-25T06:34:10.812Z
Learnt from: CR
Repo: wso2/vscode-extensions PR: 0
File: workspaces/ballerina/component-diagram/AGENTS.md:0-0
Timestamp: 2025-11-25T06:34:10.812Z
Learning: Applies to workspaces/ballerina/component-diagram/src/components/**/*.tsx : Use React 18.2.0 features including concurrent rendering and automatic batching; avoid class components in favor of functional components with hooks

Applied to files:

  • workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/SidePanelForms/QueryForm.tsx
  • workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/QueryServiceDesigner.tsx
  • workspaces/mi/mi-visualizer/src/MainPanel.tsx
📚 Learning: 2025-11-25T06:34:10.812Z
Learnt from: CR
Repo: wso2/vscode-extensions PR: 0
File: workspaces/ballerina/component-diagram/AGENTS.md:0-0
Timestamp: 2025-11-25T06:34:10.812Z
Learning: Applies to workspaces/ballerina/component-diagram/src/resources/icons/**/*.tsx : Create separate SVG icon components in src/resources/icons/ for all diagram icons and import them as React components

Applied to files:

  • workspaces/mi/mi-visualizer/src/MainPanel.tsx
📚 Learning: 2025-11-25T06:34:10.812Z
Learnt from: CR
Repo: wso2/vscode-extensions PR: 0
File: workspaces/ballerina/component-diagram/AGENTS.md:0-0
Timestamp: 2025-11-25T06:34:10.812Z
Learning: Applies to workspaces/ballerina/component-diagram/src/index.ts : Export the main Diagram component as the default export from the package entry point (index.ts)

Applied to files:

  • workspaces/mi/mi-visualizer/src/MainPanel.tsx
📚 Learning: 2025-11-25T06:34:10.812Z
Learnt from: CR
Repo: wso2/vscode-extensions PR: 0
File: workspaces/ballerina/component-diagram/AGENTS.md:0-0
Timestamp: 2025-11-25T06:34:10.812Z
Learning: Applies to workspaces/ballerina/component-diagram/src/components/DiagramContext.tsx : Use DiagramContext (React Context API) for state management across the diagram component, including expandedNodes and graphQLGroupOpen state

Applied to files:

  • workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/SidePanelForms/OperationForm.tsx
  • workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/SidePanelForms/ResourceForm.tsx
📚 Learning: 2025-11-26T07:49:56.428Z
Learnt from: KCSAbeywickrama
Repo: wso2/vscode-extensions PR: 653
File: workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/DataMapperUtils.ts:136-141
Timestamp: 2025-11-26T07:49:56.428Z
Learning: In workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/DataMapperUtils.ts, the goPrevViewBackButton() method is only called when in a focused view, ensuring breadcrumbs are always present. No guard for empty breadcrumbs is needed.

Applied to files:

  • workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/MainPanelForms/index.tsx
📚 Learning: 2025-11-26T06:34:09.752Z
Learnt from: KCSAbeywickrama
Repo: wso2/vscode-extensions PR: 653
File: workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/DataMapperUtils.ts:128-134
Timestamp: 2025-11-26T06:34:09.752Z
Learning: In workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/DataMapperUtils.ts, the goPrevViewBreadcrumb() method is only called when in a focused view, ensuring breadcrumbs are always present. No guard for empty breadcrumbs is needed.

Applied to files:

  • workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/MainPanelForms/index.tsx
  • workspaces/mi/mi-visualizer/src/views/Overview/ProjectStructureView.tsx
🧬 Code graph analysis (8)
workspaces/common-libs/service-designer/src/definitions.ts (1)
workspaces/mi/syntax-tree/src/syntax-tree-interfaces.ts (1)
  • Query (2007-2018)
workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/ResourceServiceDesigner.tsx (1)
workspaces/common-libs/ui-toolkit/src/components/Codicon/Codicon.tsx (1)
  • Codicon (44-56)
workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/SidePanelForms/QueryForm.tsx (2)
workspaces/mi/mi-visualizer/src/constants/index.ts (1)
  • SIDE_PANEL_WIDTH (44-44)
workspaces/mi/mi-diagram/src/components/Form/common.ts (1)
  • openPopup (50-99)
workspaces/mi/mi-visualizer/src/MainPanel.tsx (2)
workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/ResourceServiceDesigner.tsx (1)
  • DSSResourceServiceDesignerView (36-397)
workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/QueryServiceDesigner.tsx (1)
  • DSSQueryServiceDesignerView (34-229)
workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/SidePanelForms/OperationForm.tsx (3)
workspaces/ballerina/ballerina-visualizer/src/Context.tsx (1)
  • useVisualizerContext (134-134)
workspaces/common-libs/ui-toolkit/src/components/CheckBoxGroup/CheckBoxGroup.tsx (1)
  • FormCheckBox (141-167)
workspaces/mi/mi-diagram/src/components/Form/common.ts (1)
  • openPopup (50-99)
workspaces/mi/mi-visualizer/src/utils/DSSResourceForm.ts (6)
workspaces/mi/syntax-tree/src/syntax-tree-interfaces.ts (2)
  • DSSQuery (1175-1179)
  • Range (59-62)
workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/SidePanelForms/QueryForm.tsx (2)
  • QueryType (89-89)
  • QueryFormData (91-93)
workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/SidePanelForms/ResourceForm.tsx (1)
  • ResourceFormData (108-110)
workspaces/mi/mi-visualizer/src/utils/template-engine/mustache-templates/templateUtils.ts (1)
  • getXML (44-83)
workspaces/mi/mi-visualizer/src/constants/index.ts (1)
  • DSS_TEMPLATES (65-76)
workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/SidePanelForms/OperationForm.tsx (1)
  • OperationFormData (95-97)
workspaces/mi/mi-extension/src/project-explorer/activate.ts (1)
workspaces/mi/mi-extension/src/stateMachine.ts (1)
  • openView (734-784)
workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/SidePanelForms/ResourceForm.tsx (3)
workspaces/ballerina/ballerina-visualizer/src/Context.tsx (1)
  • useVisualizerContext (134-134)
workspaces/common-libs/ui-toolkit/src/components/CheckBoxGroup/CheckBoxGroup.tsx (1)
  • FormCheckBox (141-167)
workspaces/mi/mi-diagram/src/components/Form/common.ts (1)
  • openPopup (50-99)
🪛 Biome (2.1.2)
workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/QueryServiceDesigner.tsx

[error] 163-163: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.

The declaration is defined in this switch clause:

Safe fix: Wrap the declaration in a block.

(lint/correctness/noSwitchDeclarations)

workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/SidePanelForms/OperationForm.tsx

[error] 84-84: Do not add then to an object.

(lint/suspicious/noThenProperty)

workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/SidePanelForms/ResourceForm.tsx

[error] 96-96: Do not add then to an object.

(lint/suspicious/noThenProperty)

🔇 Additional comments (31)
workspaces/mi/mi-diagram/src/components/nodes/ReferenceNode/ReferenceNodeModel.ts (1)

53-64: LGTM! View reference correctly updated.

The method now opens DSSResourceServiceDesigner instead of the removed DSSServiceDesigner, aligning with the architectural changes in this PR.

workspaces/mi/mi-visualizer/src/views/Overview/ProjectStructureView.tsx (1)

130-137: LGTM! Data service view mapping updated correctly.

The artifact mapping now correctly routes to DSSResourceServiceDesigner, consistent with the view restructuring across the codebase.

workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/MainPanelForms/index.tsx (1)

270-278: LGTM! Cancel navigation updated correctly.

When canceling edits to an existing data service, users are now properly redirected to the DSSResourceServiceDesigner view, maintaining consistency with the new view architecture.

workspaces/mi/mi-extension/src/project-explorer/activate.ts (1)

382-386: LGTM! Command handler updated correctly.

The OPEN_DSS_SERVICE_DESIGNER command now correctly opens the DSSResourceServiceDesigner view, aligning with the view restructuring.

workspaces/mi/mi-core/src/state-machine-types.ts (1)

68-69: Verify the enum value naming consistency.

The enum key is DSSResourceServiceDesigner but the value is "DSSResourceDesigner" (missing "Service"). Confirm whether this abbreviated value is intentional and correctly referenced throughout the codebase, particularly in UI labels, routing, or configuration files.

workspaces/mi/syntax-tree/src/syntax-tree-interfaces.ts (1)

1159-1179: Consider making queryId optional for backward compatibility.

The queryId field is added to DSSResource (line 1162) and DSSOperation (line 1170) as required fields. If existing resources or operations don't have associated queries, this could cause issues with legacy data. Verify how these fields are used in consuming code and whether existing implementations expect queryId to always be present. If not, consider making these fields optional:

 export interface DSSResource extends STNode {
     path: string;
     method: string;
-    queryId: string;
+    queryId?: string;
     description: string;
     enableStreaming: boolean;
     returnRequestStatus: boolean;
 }

 export interface DSSOperation extends STNode {
     name: string;
-    queryId: string;
+    queryId?: string;
     description: string;
     enableStreaming: boolean;
 }
workspaces/mi/mi-diagram/src/components/sidePanel/dataServices/query.tsx (3)

71-72: Boolean parsing from string values looks correct.

The conversion from string "true" to boolean handles the case where form context values may arrive as strings. The fallback || false ensures a boolean default.


91-92: Field name renamed consistently to forceJDBCBatchRequests.

The property assignment now matches the renamed Controller field at line 326, maintaining consistency throughout the form.


324-333: Controller field name updated correctly.

The Controller name and error message key both reference forceJDBCBatchRequests, aligning with the property name change in the onClick handler.

workspaces/mi/mi-visualizer/src/utils/template-engine/mustache-templates/templateUtils.ts (2)

36-42: New query template imports are well-organized.

The imports are grouped logically with the existing DSS-related functions, maintaining good module organization.


70-79: New template cases follow established patterns.

The switch cases for EDIT_QUERY_REFERENCE, ADD_FULL_QUERY, UPDATE_QUERY_CONFIG, and UPDATE_QUERY are correctly implemented. The conditional rendering on line 79 appropriately selects between expression and SQL query templates based on data.isExpression.

workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/ResourceServiceDesigner.tsx (5)

36-36: Component renamed appropriately.

The rename from DSSServiceDesignerView to DSSResourceServiceDesignerView clearly reflects the architectural split between resource and query management.


71-71: queryId extraction with defensive null check.

The optional chaining resource.callQuery ? resource.callQuery.href : "" safely handles cases where callQuery might be undefined, providing an empty string fallback.


124-124: Operation model extended with queryId consistently.

The same pattern used for resources is applied to operations, maintaining consistency across both resource types.


237-245: New handleManageQueries function correctly opens the Query Designer view.

The function properly uses EVENT_TYPE.OPEN_VIEW and passes the required documentUri to the new DSSQueryServiceDesigner view.


321-324: "Manage Queries" button added to header.

The button is well-positioned before the REST/SOAP-specific action buttons and follows the existing pattern with Codicon icon and onClick handler.

workspaces/mi/mi-visualizer/src/constants/index.ts (1)

72-75: New DSS template constants follow established conventions.

The new template keys follow the existing naming pattern with uppercase constant names and lowercase hyphenated string values, consistent with the rest of DSS_TEMPLATES.

workspaces/mi/mi-visualizer/src/MainPanel.tsx (2)

5-6: Imports updated for new view components.

The imports correctly reference the renamed DSSResourceServiceDesignerView and the new DSSQueryServiceDesignerView from their respective module paths.


380-385: New view routing cases correctly implemented.

Both DSSResourceServiceDesigner and DSSQueryServiceDesigner cases follow the established pattern, passing syntaxTree and documentUri props. The break statements ensure proper switch termination.

workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/SidePanelForms/OperationForm.tsx (5)

24-28: New imports support enhanced form functionality.

The imports for Controller, watch, Keylookup, openPopup, and useVisualizerContext are correctly added to support the new dynamic form fields and query selection.


64-78: New queryId and useExistingQuery fields added to type and defaults.

The type definition and initialization properly include the new optional fields for query management.


82-87: Conditional validation schema is correct.

The yup .when() API with then property is the standard approach for conditional validation. The static analysis hint about noThenProperty is a false positive—this is not a Promise-like object but yup's conditional schema API.


172-196: Conditional form fields correctly render based on mode.

The logic properly shows "Use Existing Query" checkbox only during creation (!formData), and renders the Query ID selector when editing or when useExistingQuery is checked.


183-190: Potential mismatch: filterType is dssQuery but openPopup opens a datasource view.

The Keylookup component filters for dssQuery items, but the onCreateButtonClick handler calls openPopup(rpcClient, "datasource", ...). This seems inconsistent—if the user clicks to create a new item, they would expect to create a query, not a datasource.

Consider whether this should open a query creation popup instead, or if the datasource popup is intentional as a prerequisite for creating queries.

workspaces/mi/mi-visualizer/src/utils/template-engine/mustache-templates/core/DSS.ts (3)

43-47: LGTM! Query template generation looks correct.

The Mustache template correctly handles the conditional rendering of <expression> vs <sql> tags based on the isExpression flag using Mustache section syntax.


49-59: LGTM! Individual query component templates are well-structured.

The getQueryConfig, getSQLQuery, and getExpressionQuery functions provide clean, reusable template fragments for granular query editing operations.


69-71: LGTM! Query reference template handles self-closing correctly.

The template properly generates either a self-closed <call-query href="..." /> or an opening tag based on the isSelfClosed flag.

workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/SidePanelForms/QueryForm.tsx (1)

199-205: LGTM! Submit button correctly uses isDirty for enabling.

The button is appropriately disabled until the form has been modified, providing good UX by preventing unnecessary submissions.

workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/SidePanelForms/ResourceForm.tsx (2)

259-263: LGTM! Conditional checkbox display logic.

The "Use Existing Query" checkbox is correctly hidden during edit mode since the query association is already established.


265-283: Verify popup type for Query ID field creation.

The onCreateButtonClick handler opens a "datasource" popup for the Query ID field. Verify whether this is correct or if it should open a query-related popup (such as "dataService" or "query") to allow users to create a new query. Confirm the available popup types and the intended behavior for creating queries through the Keylookup component.

If a query creation popup should be used instead, update the popup type and parameters accordingly.

workspaces/mi/mi-visualizer/src/utils/DSSResourceForm.ts (1)

50-58: LGTM! Clean data mapping function.

The generateQueryData function provides a straightforward mapping from the DSSQuery model to the form-compatible QueryType.

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

♻️ Duplicate comments (2)
workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/QueryServiceDesigner.tsx (2)

160-174: Wrap switch case declaration in a block to prevent scope leakage.

The let dbName declaration inside the "create" case can be accessed by other cases, which could lead to confusing bugs. Wrap the case body in a block.

     const handleQueryCreate = (formData: QueryFormData) => {
         switch (formData.mode) {
-            case "create":
-                let dbName = "";
+            case "create": {
+                const dbName = syntaxTree.data.configs?.[0]?.id ?? "";
-                if (syntaxTree.data.configs !== undefined && syntaxTree.data.configs !== null && syntaxTree.data.configs.length > 0) {
-                    dbName = syntaxTree.data.configs[0].id;
-                }
                 onQueryCreate(formData, queryBodyRange, documentUri, rpcClient, dbName);
                 break;
+            }
             case "edit":
                 onQueryEdit(formData, selectedQuery, documentUri, rpcClient);
                 break;
         }
         setQueryFormOpen(false);
     };

220-226: Conditional formData prop may cause unexpected behavior.

The expression mode === "edit" && formData evaluates to false (a boolean) when mode !== "edit", not undefined. This could cause type issues if QueryForm expects QueryType | undefined.

             <QueryForm
                 isOpen={isQueryFormOpen}
-                formData={mode === "edit" && formData}
+                formData={mode === "edit" ? formData : undefined}
                 onCancel={handleCancel}
                 documentUri={documentUri}
                 onSave={handleQueryCreate}
             />
🧹 Nitpick comments (8)
workspaces/mi/mi-core/src/state-machine-types.ts (1)

68-69: Inconsistent naming pattern in enum values.

The enum values use different naming conventions:

  • DSSResourceServiceDesigner = "DSSResourceDesigner" (no spaces)
  • DSSQueryServiceDesigner = "DSS Query Designer" (with spaces)

For consistency with similar entries like DataServiceForm = "Data Service Form" and ServiceDesigner = "Service Designer", consider aligning the values:

-    DSSResourceServiceDesigner = "DSSResourceDesigner",
-    DSSQueryServiceDesigner = "DSS Query Designer",
+    DSSResourceServiceDesigner = "DSS Resource Designer",
+    DSSQueryServiceDesigner = "DSS Query Designer",
workspaces/mi/mi-visualizer/src/constants/index.ts (1)

72-75: Inconsistent naming prefix in new template keys.

Existing DSS templates consistently use the dss prefix (e.g., add-dss-resource, edit-dss-operation), but the new entries are inconsistent:

  • ADD_FULL_QUERY"add-full-dss-query"
  • UPDATE_QUERY_CONFIG"update-query-config" (missing dss)
  • UPDATE_QUERY"update-query" (missing dss)
  • EDIT_QUERY_REFERENCE"edit-query-reference" (missing dss)

Consider aligning for consistency:

     ADD_FULL_QUERY: "add-full-dss-query",
-    UPDATE_QUERY_CONFIG: "update-query-config",
-    UPDATE_QUERY: "update-query",
-    EDIT_QUERY_REFERENCE: "edit-query-reference"
+    UPDATE_QUERY_CONFIG: "update-dss-query-config",
+    UPDATE_QUERY: "update-dss-query",
+    EDIT_QUERY_REFERENCE: "edit-dss-query-reference"
workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/QueryServiceDesigner.tsx (2)

36-41: Consider using more specific types instead of any.

Several state variables use any type which reduces type safety. Consider defining proper types for queryBodyRange, formData, and selectedQuery to catch potential bugs at compile time.

-    const [queryBodyRange, setQueryBodyRange] = React.useState<any>(null);
-    const [formData, setFormData] = React.useState<any>(null);
-    const [selectedQuery, setSelectedQuery] = React.useState(null);
+    const [queryBodyRange, setQueryBodyRange] = React.useState<Range | null>(null);
+    const [formData, setFormData] = React.useState<QueryType | null>(null);
+    const [selectedQuery, setSelectedQuery] = React.useState<any>(null);

You would need to import Range from the syntax-tree package and QueryType from the QueryForm module.


130-139: Unused function openDiagram may be dead code.

The openDiagram function is defined but only called from handleQueryClick. However, the variable queryIndex on line 131 is computed but never used.

     const openDiagram = (query: Resource) => {
-        const queryIndex = queryServiceModel.resources.findIndex((res) => res === query);
         const href = query.path;

         if (!href) {
             rpcClient.getMiDiagramRpcClient().showErrorMessage({ message: "Cannot find the query for selected resource" });
             return;
         }
         rpcClient.getMiVisualizerRpcClient().openView({ type: EVENT_TYPE.OPEN_VIEW, location: { view: MACHINE_VIEW.DataServiceView, documentUri: documentUri, identifier: href } })
     }
workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/SidePanelForms/QueryForm.tsx (2)

44-69: Remove unused styled components.

The Section namespace and AddButtonWrapper styled components are defined but never used in this file. Consider removing them to reduce code clutter.

-namespace Section {
-    export const Container = styled.div`
-        display: flex;
-        flex-direction: column;
-        gap: 10px;
-    `;
-
-    export const Title = styled.h4`
-        display: flex;
-        align-items: center;
-        margin: 0;
-        padding: 2px;
-        width: 100%;
-    `;
-
-    export const IconContainer = styled.div`
-        margin-left: auto;
-    `;
-}
-
-const AddButtonWrapper = styled.div`
-	margin: 8px 0;
-	display: flex;
-	justify-content: flex-end;
-	gap: 20px;
-`;

106-118: Remove unused destructured variables from useForm.

watch and setValue are destructured from useForm but are not used anywhere in the component.

     const {
         control,
         handleSubmit,
         formState: { errors, isDirty },
         register,
-        watch,
-        setValue,
         reset
     } = useForm({
         defaultValues: newQuery,
         resolver: yupResolver(schema),
         mode: "onChange",
     });
workspaces/mi/mi-visualizer/src/utils/DSSResourceForm.ts (2)

122-153: Missing error handling for async operations.

The promise chain in onQueryCreate doesn't handle rejections. If getQueryType or applyEdit fails, the error will be silently swallowed.

Consider adding error handling:

     getQueryType(rpcClient, documentUri, data.datasource)
         .then((queryType) => {
             const queryContent = getXML(DSS_TEMPLATES.ADD_FULL_QUERY, {
                 ...formValues,
                 isExpression: queryType === "expression"
             });

             return rpcClient.getMiDiagramRpcClient().applyEdit({
                 text: queryContent,
                 documentUri,
                 range: {
                     start: {
                         line: range.end.line,
                         character: range.end.character,
                     },
                     end: {
                         line: range.end.line,
                         character: range.end.character,
                     }
                 }
             });
-        });
+        })
+        .catch((error) => {
+            rpcClient.getMiDiagramRpcClient().showErrorMessage({ 
+                message: `Failed to create query: ${error.message}` 
+            });
+        });

270-285: Simplify getQueryType using Array methods.

The function can be simplified using find() and some() instead of nested forEach loops.

 async function getQueryType(rpcClient: RpcClient, documentUri: string, datasource: string): Promise<string> {
-    let queryType = "sql";
     const existingDataService = await rpcClient.getMiDiagramRpcClient().getDataService({ path: documentUri });
-    existingDataService.datasources.forEach((ds) => {
-        if (ds.dataSourceName === datasource) {
-            const propertyKeys: string[] = [];
-            ds.datasourceProperties.forEach((attr: any) => {
-                propertyKeys.push(attr.key);
-            });
-            if (propertyKeys.includes("mongoDB_servers")) {
-                queryType = "expression";
-            }
-        }
-    });
-    return queryType;
+    const matchingDs = existingDataService.datasources.find(
+        (ds) => ds.dataSourceName === datasource
+    );
+    if (matchingDs?.datasourceProperties?.some((attr: any) => attr.key === "mongoDB_servers")) {
+        return "expression";
+    }
+    return "sql";
 }
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 824ce36 and 97d7018.

📒 Files selected for processing (19)
  • workspaces/common-libs/service-designer/src/definitions.ts (1 hunks)
  • workspaces/mi/mi-core/src/state-machine-types.ts (1 hunks)
  • workspaces/mi/mi-diagram/src/components/Form/common.ts (1 hunks)
  • workspaces/mi/mi-diagram/src/components/nodes/ReferenceNode/ReferenceNodeModel.ts (1 hunks)
  • workspaces/mi/mi-diagram/src/components/sidePanel/dataServices/query.tsx (3 hunks)
  • workspaces/mi/mi-extension/src/project-explorer/activate.ts (1 hunks)
  • workspaces/mi/mi-visualizer/src/MainPanel.tsx (2 hunks)
  • workspaces/mi/mi-visualizer/src/constants/index.ts (1 hunks)
  • workspaces/mi/mi-visualizer/src/utils/DSSResourceForm.ts (11 hunks)
  • workspaces/mi/mi-visualizer/src/utils/template-engine/mustache-templates/core/DSS.ts (1 hunks)
  • workspaces/mi/mi-visualizer/src/utils/template-engine/mustache-templates/templateUtils.ts (2 hunks)
  • workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/MainPanelForms/index.tsx (1 hunks)
  • workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/QueryServiceDesigner.tsx (1 hunks)
  • workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/ResourceServiceDesigner.tsx (5 hunks)
  • workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/SidePanelForms/OperationForm.tsx (5 hunks)
  • workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/SidePanelForms/QueryForm.tsx (1 hunks)
  • workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/SidePanelForms/ResourceForm.tsx (5 hunks)
  • workspaces/mi/mi-visualizer/src/views/Overview/ProjectStructureView.tsx (1 hunks)
  • workspaces/mi/syntax-tree/src/syntax-tree-interfaces.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (9)
  • workspaces/mi/mi-diagram/src/components/Form/common.ts
  • workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/MainPanelForms/index.tsx
  • workspaces/mi/mi-visualizer/src/views/Overview/ProjectStructureView.tsx
  • workspaces/mi/mi-diagram/src/components/sidePanel/dataServices/query.tsx
  • workspaces/mi/mi-visualizer/src/utils/template-engine/mustache-templates/core/DSS.ts
  • workspaces/mi/mi-visualizer/src/MainPanel.tsx
  • workspaces/mi/mi-extension/src/project-explorer/activate.ts
  • workspaces/mi/mi-diagram/src/components/nodes/ReferenceNode/ReferenceNodeModel.ts
  • workspaces/common-libs/service-designer/src/definitions.ts
🧰 Additional context used
🧠 Learnings (6)
📚 Learning: 2025-11-25T06:34:10.812Z
Learnt from: CR
Repo: wso2/vscode-extensions PR: 0
File: workspaces/ballerina/component-diagram/AGENTS.md:0-0
Timestamp: 2025-11-25T06:34:10.812Z
Learning: Applies to workspaces/ballerina/component-diagram/src/**/*.{ts,tsx} : Define all constants (node types, sizing, spacing) in src/resources/constants.ts and import them where needed instead of hardcoding values

Applied to files:

  • workspaces/mi/mi-visualizer/src/constants/index.ts
📚 Learning: 2025-11-25T06:34:10.812Z
Learnt from: CR
Repo: wso2/vscode-extensions PR: 0
File: workspaces/ballerina/component-diagram/AGENTS.md:0-0
Timestamp: 2025-11-25T06:34:10.812Z
Learning: Applies to workspaces/ballerina/component-diagram/src/components/DiagramContext.tsx : Use DiagramContext (React Context API) for state management across the diagram component, including expandedNodes and graphQLGroupOpen state

Applied to files:

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

Applied to files:

  • workspaces/mi/mi-visualizer/src/utils/DSSResourceForm.ts
  • workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/SidePanelForms/QueryForm.tsx
  • workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/QueryServiceDesigner.tsx
📚 Learning: 2025-11-24T14:51:49.267Z
Learnt from: KCSAbeywickrama
Repo: wso2/vscode-extensions PR: 998
File: workspaces/ballerina/data-mapper/src/components/DataMapper/Header/ExpressionBar.tsx:113-132
Timestamp: 2025-11-24T14:51:49.267Z
Learning: In workspaces/ballerina/data-mapper/src/components/DataMapper/Header/ExpressionBar.tsx, if `textFieldRef.current` is not undefined, `textFieldRef.current.inputElement` is guaranteed to exist. If `inputElement` doesn't exist when `current` exists, it's a fatal error that should reach the error boundary rather than being handled with defensive null checks.

Applied to files:

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

Applied to files:

  • workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/SidePanelForms/QueryForm.tsx
  • workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/QueryServiceDesigner.tsx
📚 Learning: 2025-11-20T11:04:33.712Z
Learnt from: KCSAbeywickrama
Repo: wso2/vscode-extensions PR: 898
File: workspaces/ballerina/data-mapper/src/components/DataMapper/SidePanel/QueryClauses/ClausesPanel.tsx:38-38
Timestamp: 2025-11-20T11:04:33.712Z
Learning: In workspaces/ballerina/data-mapper/src/components/DataMapper/SidePanel/QueryClauses/ClausesPanel.tsx, the use of `useDMQueryClausesPanelStore.getState()` to access `clauseToAdd` and `setClauseToAdd` (instead of the hook subscription pattern) is intentional to prevent re-renders when these state values change.

Applied to files:

  • workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/SidePanelForms/QueryForm.tsx
🧬 Code graph analysis (7)
workspaces/mi/mi-visualizer/src/utils/template-engine/mustache-templates/templateUtils.ts (2)
workspaces/mi/mi-visualizer/src/constants/index.ts (1)
  • DSS_TEMPLATES (65-76)
workspaces/mi/mi-visualizer/src/utils/template-engine/mustache-templates/core/DSS.ts (6)
  • getEditQueryReferenceTemplate (69-71)
  • getAddQuery (37-41)
  • getAddFullQuery (43-47)
  • getQueryConfig (49-51)
  • getExpressionQuery (57-59)
  • getSQLQuery (53-55)
workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/ResourceServiceDesigner.tsx (1)
workspaces/common-libs/ui-toolkit/src/components/Codicon/Codicon.tsx (1)
  • Codicon (44-56)
workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/SidePanelForms/OperationForm.tsx (3)
workspaces/ballerina/ballerina-visualizer/src/Context.tsx (1)
  • useVisualizerContext (134-134)
workspaces/common-libs/ui-toolkit/src/components/CheckBoxGroup/CheckBoxGroup.tsx (1)
  • FormCheckBox (141-167)
workspaces/mi/mi-diagram/src/components/Form/common.ts (1)
  • openPopup (50-99)
workspaces/mi/mi-visualizer/src/utils/DSSResourceForm.ts (5)
workspaces/mi/syntax-tree/src/syntax-tree-interfaces.ts (2)
  • DSSQuery (1175-1179)
  • Range (59-62)
workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/SidePanelForms/QueryForm.tsx (2)
  • QueryType (89-89)
  • QueryFormData (91-93)
workspaces/mi/mi-rpc-client/src/RpcClient.ts (1)
  • RpcClient (30-137)
workspaces/mi/mi-visualizer/src/utils/template-engine/mustache-templates/templateUtils.ts (1)
  • getXML (44-83)
workspaces/mi/mi-visualizer/src/constants/index.ts (1)
  • DSS_TEMPLATES (65-76)
workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/SidePanelForms/QueryForm.tsx (2)
workspaces/mi/mi-visualizer/src/constants/index.ts (1)
  • SIDE_PANEL_WIDTH (44-44)
workspaces/mi/mi-diagram/src/components/Form/common.ts (1)
  • openPopup (50-99)
workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/SidePanelForms/ResourceForm.tsx (3)
workspaces/ballerina/ballerina-visualizer/src/Context.tsx (1)
  • useVisualizerContext (134-134)
workspaces/common-libs/ui-toolkit/src/components/CheckBoxGroup/CheckBoxGroup.tsx (1)
  • FormCheckBox (141-167)
workspaces/mi/mi-diagram/src/components/Form/common.ts (1)
  • openPopup (50-99)
workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/QueryServiceDesigner.tsx (2)
workspaces/mi/mi-visualizer/src/utils/DSSResourceForm.ts (3)
  • generateQueryData (50-58)
  • onQueryCreate (122-153)
  • onQueryEdit (237-268)
workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/SidePanelForms/QueryForm.tsx (2)
  • QueryFormData (91-93)
  • QueryForm (103-212)
🪛 Biome (2.1.2)
workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/SidePanelForms/OperationForm.tsx

[error] 84-84: Do not add then to an object.

(lint/suspicious/noThenProperty)

workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/SidePanelForms/ResourceForm.tsx

[error] 96-96: Do not add then to an object.

(lint/suspicious/noThenProperty)

workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/QueryServiceDesigner.tsx

[error] 163-163: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.

The declaration is defined in this switch clause:

Safe fix: Wrap the declaration in a block.

(lint/correctness/noSwitchDeclarations)

🔇 Additional comments (15)
workspaces/mi/syntax-tree/src/syntax-tree-interfaces.ts (3)

1159-1166: LGTM on queryId addition to DSSResource.

The queryId field correctly captures the query reference for resources, aligning with the extraction logic in ResourceServiceDesigner.tsx where it's derived from resource.callQuery.href.


1168-1173: LGTM on queryId addition to DSSOperation.

Consistent with the DSSResource change, enabling query reference tracking for operations.


1175-1179: Verify if DSSQuery interface should include additional fields from Query.

The new DSSQuery interface is minimal with only name, datasource, and query fields. The existing Query interface (lines 2007-2018) includes many additional fields like params, result, returnGeneratedKeys, sql, expression, useConfig, etc.

If DSSQuery is intended as a simplified UI/form model, consider adding a comment to clarify its purpose and relationship to Query. Otherwise, verify that critical fields aren't missing for the query management workflows.

workspaces/mi/mi-visualizer/src/utils/template-engine/mustache-templates/templateUtils.ts (2)

36-42: LGTM on extended imports.

The new imports correctly correspond to the template functions defined in core/DSS.ts for query-related operations.


70-79: LGTM on new template rendering cases.

The new switch cases correctly handle the query-related templates:

  • EDIT_QUERY_REFERENCE, ADD_FULL_QUERY, and UPDATE_QUERY_CONFIG follow the established pattern
  • UPDATE_QUERY correctly uses conditional logic to render either expression or SQL format based on data.isExpression
workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/ResourceServiceDesigner.tsx (5)

36-36: LGTM on component rename.

The rename from DSSServiceDesignerView to DSSResourceServiceDesignerView correctly reflects the split between resource-focused and query-focused designer views.


71-71: LGTM on queryId extraction for resources.

Correctly extracts queryId from resource.callQuery.href with an empty string fallback when callQuery is undefined.


124-124: LGTM on queryId extraction for operations.

Consistent with the resource extraction pattern.


237-245: LGTM on handleManageQueries implementation.

The function correctly opens the DSSQueryServiceDesigner view using the RPC client with the current documentUri context.


321-324: LGTM on header updates and Manage Queries button.

The title update to "Data Service Resource Designer" and the new "Manage Queries" button correctly integrate with the redesigned DSS workflow. The button follows the same pattern as existing buttons with Codicon icons.

workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/SidePanelForms/OperationForm.tsx (1)

80-91: Yup conditional validation syntax is correct.

The static analysis warning about then property is a false positive. This is the standard yup conditional validation API using .when() with is, then, and otherwise callbacks.

workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/SidePanelForms/QueryForm.tsx (1)

103-133: Well-structured form component following established patterns.

The component correctly uses react-hook-form with yup validation, properly resets form state based on isOpen and formData props, and handles create/edit mode appropriately.

workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/SidePanelForms/ResourceForm.tsx (1)

71-104: Schema and type extensions look correct.

The addition of queryId and useExistingQuery fields with conditional validation is properly implemented. The yup .when() syntax is the standard approach for conditional validation.

workspaces/mi/mi-visualizer/src/utils/DSSResourceForm.ts (2)

50-58: New generateQueryData utility follows established patterns.

The function correctly maps DSSQuery model fields to QueryType, consistent with generateResourceData and generateOperationData.


186-194: Null checks for referenceQueryTagRange properly implemented.

The conditional checks before applying query reference edits address the previously raised concerns about potential null references.

Also applies to: 225-233

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

♻️ Duplicate comments (6)
workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/SidePanelForms/ResourceForm.tsx (1)

259-283: Incorrect popup view for Query ID lookup.

The Keylookup for "Query ID" with filterType='dssQuery' has an onCreateButtonClick handler that opens a "datasource" popup, which is inconsistent with the field's purpose. Since allowItemCreate={false}, this handler will never be invoked and is effectively dead code, but it's still confusing.

Remove the unnecessary handler:

                             <Keylookup
                                 value={field.value}
                                 filterType='dssQuery'
                                 label="Query ID"
                                 allowItemCreate={false}
-                                onCreateButtonClick={(fetchItems: any, handleValueChange: any) => {
-                                    openPopup(rpcClient, "datasource", fetchItems, handleValueChange, documentUri, { datasource: undefined });
-                                }}
                                 onValueChange={field.onChange}
                                 required={true}
                             />
workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/QueryServiceDesigner.tsx (2)

160-174: Wrap switch case declaration in a block to prevent scope leakage.

The let dbName declaration inside the switch case can be accessed by other cases, which could lead to confusing bugs.

     const handleQueryCreate = (formData: QueryFormData) => {
         switch (formData.mode) {
-            case "create":
-                let dbName = "";
+            case "create": {
+                let dbName = "";
                 if (syntaxTree.data.configs !== undefined && syntaxTree.data.configs !== null && syntaxTree.data.configs.length > 0) {
                     dbName = syntaxTree.data.configs[0].id;
                 }
                 onQueryCreate(formData, queryBodyRange, documentUri, rpcClient, dbName);
                 break;
+            }
             case "edit":
                 onQueryEdit(formData, selectedQuery, documentUri, rpcClient);
                 break;
         }
         setQueryFormOpen(false);
     };

220-226: Conditional formData prop may cause unexpected behavior.

The expression mode === "edit" && formData evaluates to false (a boolean) when mode !== "edit", not undefined. This could cause type issues if QueryForm expects QueryType | undefined.

             <QueryForm
                 isOpen={isQueryFormOpen}
-                formData={mode === "edit" && formData}
+                formData={mode === "edit" ? formData : undefined}
                 onCancel={handleCancel}
                 documentUri={documentUri}
                 onSave={handleQueryCreate}
             />
workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/SidePanelForms/OperationForm.tsx (1)

178-196: Incorrect popup view for Query ID lookup.

The Keylookup for "Query ID" with filterType='dssQuery' has an onCreateButtonClick handler that opens a "datasource" popup, which is inconsistent with the field's purpose. Since allowItemCreate={false}, this handler will never be invoked.

Remove the unnecessary handler:

                         <Keylookup
                             value={field.value}
                             filterType='dssQuery'
                             label="Query ID"
                             allowItemCreate={false}
-                            onCreateButtonClick={(fetchItems: any, handleValueChange: any) => {
-                                openPopup(rpcClient, "datasource", fetchItems, handleValueChange, documentUri, { datasource: undefined });
-                            }}
                             onValueChange={field.onChange}
                             required={true}
                         />
workspaces/mi/mi-visualizer/src/utils/DSSResourceForm.ts (2)

94-95: Handle undefined queryId in operation creation.

Same issue as in onResourceCreate: the code doesn't handle undefined queryId, only empty string.

Apply this diff:

-    const queryName = data.queryId !== "" ? data.queryId : data.operationName.replace(/[^a-zA-Z]/g, '').toLowerCase() + "_query";
-    const shouldCreateQuery = data.queryId === "";
+    const queryName = data.queryId || data.operationName.replace(/[^a-zA-Z]/g, '').toLowerCase() + "_query";
+    const shouldCreateQuery = !data.queryId;

62-63: Handle undefined queryId in addition to empty string.

The current code only checks for empty string (""), but queryId is optional and could be undefined. When undefined, line 62 evaluates undefined !== "" as true, assigning undefined to queryName, which will then be passed to the template and likely cause issues.

Apply this diff to handle both empty string and undefined:

-    const queryName = data.queryId !== "" ? data.queryId :data.resourceMethod.toLowerCase() + "_" + data.resourcePath.replace(/[^a-zA-Z]/g, '').toLowerCase() + "_query";
-    const shouldCreateQuery = data.queryId === "";
+    const queryName = data.queryId || data.resourceMethod.toLowerCase() + "_" + data.resourcePath.replace(/[^a-zA-Z]/g, '').toLowerCase() + "_query";
+    const shouldCreateQuery = !data.queryId;
🧹 Nitpick comments (10)
workspaces/mi/syntax-tree/src/syntax-tree-interfaces.ts (1)

1159-1179: Consider making queryId optional on DSSResource and DSSOperation.

In ResourceServiceDesigner.tsx, queryId is derived as resource.callQuery ? resource.callQuery.href : "", suggesting that a query reference may not always be present. Making queryId optional (queryId?: string) would better model this optionality at the type level and align with how it's used in the UI layer.

 export interface DSSResource extends STNode {
     path: string;
     method: string;
-    queryId: string;
+    queryId?: string;
     description: string;
     enableStreaming: boolean;
     returnRequestStatus: boolean;
 }

 export interface DSSOperation extends STNode {
     name: string;
-    queryId: string;
+    queryId?: string;
     description: string;
     enableStreaming: boolean;
 }
workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/ResourceServiceDesigner.tsx (1)

71-71: Consider using optional chaining for consistency.

The queryId extraction could use optional chaining for slightly cleaner code:

-                queryId: resource.callQuery ? resource.callQuery.href : "",
+                queryId: resource.callQuery?.href ?? "",
-                queryId: operation.callQuery ? operation.callQuery.href : "",
+                queryId: operation.callQuery?.href ?? "",

Also applies to: 124-124

workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/QueryServiceDesigner.tsx (1)

130-139: Remove unused variable queryIndex.

The queryIndex variable is calculated but never used, which is dead code.

     const openDiagram = (query: Resource) => {
-        const queryIndex = queryServiceModel.resources.findIndex((res) => res === query);
         const href = query.path;

         if (!href) {
             rpcClient.getMiDiagramRpcClient().showErrorMessage({ message: "Cannot find the query for selected resource" });
             return;
         }
         rpcClient.getMiVisualizerRpcClient().openView({ type: EVENT_TYPE.OPEN_VIEW, location: { view: MACHINE_VIEW.DataServiceView, documentUri: documentUri, identifier: href } })
     }
workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/SidePanelForms/QueryForm.tsx (4)

64-69: Remove unused styled component.

AddButtonWrapper is defined but never used in this component.

Apply this diff to remove the unused code:

-const AddButtonWrapper = styled.div`
-	margin: 8px 0;
-	display: flex;
-	justify-content: flex-end;
-	gap: 20px;
-`;
-

120-126: Include reset in the useEffect dependency array.

While reset from react-hook-form is stable, it's best practice to include all referenced variables in the dependency array to satisfy ESLint rules and avoid potential issues.

Apply this diff:

-    }, [formData, isOpen])
+    }, [formData, isOpen, reset])

135-141: Simplify error message handling.

The .toString() call on line 138 is redundant since yup validation messages are already strings.

Apply this diff:

-            errorMsg: errors[fieldName] && errors[fieldName].message.toString(),
+            errorMsg: errors[fieldName]?.message,

161-161: Consider using styled-components for consistency.

The inline style prop on SidePanelBody is inconsistent with the styled-components pattern used throughout this file.

Consider creating a styled wrapper:

const ScrollableSidePanelBody = styled(SidePanelBody)`
    overflow-y: scroll;
`;

Then use:

-            <SidePanelBody style={{ overflowY: "scroll" }}>
+            <ScrollableSidePanelBody>
workspaces/mi/mi-visualizer/src/utils/DSSResourceForm.ts (3)

130-151: Add error handling for the promise chain.

The getQueryType promise chain lacks error handling. If getQueryType or applyEdit fails, the error will be unhandled, potentially leaving the UI in an inconsistent state.

Add a .catch() handler:

             });
-        });
+        })
+        .catch((error) => {
+            console.error("Failed to create query:", error);
+            // Consider showing user-facing error message
+        });

246-266: Add error handling for query edit promise chain.

Similar to onQueryCreate, this promise chain lacks error handling.

Add a .catch() handler:

             });
-        });
+        })
+        .catch((error) => {
+            console.error("Failed to edit query:", error);
+            // Consider showing user-facing error message
+        });

270-285: Add error handling for RPC call in getQueryType.

The getDataService RPC call on line 272 could fail, but there's no try-catch block. This would cause the promise to reject, propagating to callers.

Wrap in try-catch and provide a safe default:

 async function getQueryType(rpcClient: RpcClient, documentUri: string, datasource: string): Promise<string> {
     let queryType = "sql";
-    const existingDataService = await rpcClient.getMiDiagramRpcClient().getDataService({ path: documentUri });
-    existingDataService.datasources.forEach((ds) => {
-        if (ds.dataSourceName === datasource) {
-            const propertyKeys: string[] = [];
-            ds.datasourceProperties.forEach((attr: any) => {
-                propertyKeys.push(attr.key);
-            });
-            if (propertyKeys.includes("mongoDB_servers")) {
-                queryType = "expression";
-            }
-        }
-    });
+    try {
+        const existingDataService = await rpcClient.getMiDiagramRpcClient().getDataService({ path: documentUri });
+        existingDataService.datasources.forEach((ds) => {
+            if (ds.dataSourceName === datasource) {
+                const propertyKeys: string[] = [];
+                ds.datasourceProperties.forEach((attr: any) => {
+                    propertyKeys.push(attr.key);
+                });
+                if (propertyKeys.includes("mongoDB_servers")) {
+                    queryType = "expression";
+                }
+            }
+        });
+    } catch (error) {
+        console.error("Failed to determine query type:", error);
+        // Default to "sql" on error
+    }
     return queryType;
 }
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 97d7018 and 017146a.

📒 Files selected for processing (20)
  • workspaces/common-libs/service-designer/src/definitions.ts (1 hunks)
  • workspaces/mi/mi-core/src/state-machine-types.ts (1 hunks)
  • workspaces/mi/mi-diagram/src/components/Form/common.ts (1 hunks)
  • workspaces/mi/mi-diagram/src/components/nodes/ReferenceNode/ReferenceNodeModel.ts (1 hunks)
  • workspaces/mi/mi-diagram/src/components/sidePanel/dataServices/query.tsx (3 hunks)
  • workspaces/mi/mi-extension/src/project-explorer/activate.ts (1 hunks)
  • workspaces/mi/mi-extension/src/test/e2e-playwright-tests/components/ArtifactTest/DataService.ts (5 hunks)
  • workspaces/mi/mi-visualizer/src/MainPanel.tsx (2 hunks)
  • workspaces/mi/mi-visualizer/src/constants/index.ts (1 hunks)
  • workspaces/mi/mi-visualizer/src/utils/DSSResourceForm.ts (11 hunks)
  • workspaces/mi/mi-visualizer/src/utils/template-engine/mustache-templates/core/DSS.ts (1 hunks)
  • workspaces/mi/mi-visualizer/src/utils/template-engine/mustache-templates/templateUtils.ts (2 hunks)
  • workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/MainPanelForms/index.tsx (1 hunks)
  • workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/QueryServiceDesigner.tsx (1 hunks)
  • workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/ResourceServiceDesigner.tsx (5 hunks)
  • workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/SidePanelForms/OperationForm.tsx (5 hunks)
  • workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/SidePanelForms/QueryForm.tsx (1 hunks)
  • workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/SidePanelForms/ResourceForm.tsx (5 hunks)
  • workspaces/mi/mi-visualizer/src/views/Overview/ProjectStructureView.tsx (1 hunks)
  • workspaces/mi/syntax-tree/src/syntax-tree-interfaces.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (7)
  • workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/MainPanelForms/index.tsx
  • workspaces/mi/mi-diagram/src/components/nodes/ReferenceNode/ReferenceNodeModel.ts
  • workspaces/common-libs/service-designer/src/definitions.ts
  • workspaces/mi/mi-diagram/src/components/sidePanel/dataServices/query.tsx
  • workspaces/mi/mi-visualizer/src/constants/index.ts
  • workspaces/mi/mi-diagram/src/components/Form/common.ts
  • workspaces/mi/mi-core/src/state-machine-types.ts
🧰 Additional context used
🧠 Learnings (16)
📚 Learning: 2025-11-25T06:34:10.812Z
Learnt from: CR
Repo: wso2/vscode-extensions PR: 0
File: workspaces/ballerina/component-diagram/AGENTS.md:0-0
Timestamp: 2025-11-25T06:34:10.812Z
Learning: Applies to workspaces/ballerina/component-diagram/src/**/*.{ts,tsx} : Define all constants (node types, sizing, spacing) in src/resources/constants.ts and import them where needed instead of hardcoding values

Applied to files:

  • workspaces/mi/mi-visualizer/src/views/Overview/ProjectStructureView.tsx
  • workspaces/mi/mi-extension/src/test/e2e-playwright-tests/components/ArtifactTest/DataService.ts
  • workspaces/mi/mi-visualizer/src/MainPanel.tsx
📚 Learning: 2025-11-26T07:49:56.428Z
Learnt from: KCSAbeywickrama
Repo: wso2/vscode-extensions PR: 653
File: workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/DataMapperUtils.ts:136-141
Timestamp: 2025-11-26T07:49:56.428Z
Learning: In workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/DataMapperUtils.ts, the goPrevViewBackButton() method is only called when in a focused view, ensuring breadcrumbs are always present. No guard for empty breadcrumbs is needed.

Applied to files:

  • workspaces/mi/mi-extension/src/test/e2e-playwright-tests/components/ArtifactTest/DataService.ts
📚 Learning: 2025-11-26T06:34:09.752Z
Learnt from: KCSAbeywickrama
Repo: wso2/vscode-extensions PR: 653
File: workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/DataMapperUtils.ts:128-134
Timestamp: 2025-11-26T06:34:09.752Z
Learning: In workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/DataMapperUtils.ts, the goPrevViewBreadcrumb() method is only called when in a focused view, ensuring breadcrumbs are always present. No guard for empty breadcrumbs is needed.

Applied to files:

  • workspaces/mi/mi-extension/src/test/e2e-playwright-tests/components/ArtifactTest/DataService.ts
📚 Learning: 2025-11-26T06:35:19.217Z
Learnt from: KCSAbeywickrama
Repo: wso2/vscode-extensions PR: 653
File: workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/DataMapperUtils.ts:173-178
Timestamp: 2025-11-26T06:35:19.217Z
Learning: In workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/DataMapperUtils.ts, the commented-out debugging block in the verifyFileContent function (lines 172-177 containing console.log, page.pause, and updateDataFileSync) is intentionally kept as a developer utility for updating test data files when needed. It should not be removed.

Applied to files:

  • workspaces/mi/mi-extension/src/test/e2e-playwright-tests/components/ArtifactTest/DataService.ts
📚 Learning: 2025-11-25T06:34:10.812Z
Learnt from: CR
Repo: wso2/vscode-extensions PR: 0
File: workspaces/ballerina/component-diagram/AGENTS.md:0-0
Timestamp: 2025-11-25T06:34:10.812Z
Learning: Applies to workspaces/ballerina/component-diagram/src/**/*.test.{ts,tsx} : Create snapshot tests for all node widgets and verify visual consistency across renders

Applied to files:

  • workspaces/mi/mi-extension/src/test/e2e-playwright-tests/components/ArtifactTest/DataService.ts
📚 Learning: 2025-11-26T06:33:22.950Z
Learnt from: KCSAbeywickrama
Repo: wso2/vscode-extensions PR: 653
File: workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/DataMapperUtils.ts:86-112
Timestamp: 2025-11-26T06:33:22.950Z
Learning: In workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/DataMapperUtils.ts, empty catch blocks around progress ring waitForSelector calls (state: 'attached' and 'detached') are intentional. The progress ring duration depends on machine performance and may appear very briefly, causing the wait to miss the event. The try-catch allows the test to proceed gracefully regardless of timing.

Applied to files:

  • workspaces/mi/mi-extension/src/test/e2e-playwright-tests/components/ArtifactTest/DataService.ts
📚 Learning: 2025-11-26T06:37:07.886Z
Learnt from: KCSAbeywickrama
Repo: wso2/vscode-extensions PR: 653
File: workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/dm-data/array-inner/inline/map3.bal.txt:6-8
Timestamp: 2025-11-26T06:37:07.886Z
Learning: In workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/dm-data/ directories, BAL test data files (such as those in array-inner/inline/, array-root/inline/, basic/inline/, and their reusable counterparts) may intentionally contain type errors and other violations. These are comparison files used to test data mapper functionality and error handling, so such errors should not be flagged as issues.

Applied to files:

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

Applied to files:

  • workspaces/mi/mi-visualizer/src/MainPanel.tsx
  • workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/SidePanelForms/QueryForm.tsx
  • workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/QueryServiceDesigner.tsx
📚 Learning: 2025-11-25T06:34:10.812Z
Learnt from: CR
Repo: wso2/vscode-extensions PR: 0
File: workspaces/ballerina/component-diagram/AGENTS.md:0-0
Timestamp: 2025-11-25T06:34:10.812Z
Learning: Applies to workspaces/ballerina/component-diagram/src/resources/icons/**/*.tsx : Create separate SVG icon components in src/resources/icons/ for all diagram icons and import them as React components

Applied to files:

  • workspaces/mi/mi-visualizer/src/MainPanel.tsx
📚 Learning: 2025-11-25T06:34:10.812Z
Learnt from: CR
Repo: wso2/vscode-extensions PR: 0
File: workspaces/ballerina/component-diagram/AGENTS.md:0-0
Timestamp: 2025-11-25T06:34:10.812Z
Learning: Applies to workspaces/ballerina/component-diagram/src/index.ts : Export the main Diagram component as the default export from the package entry point (index.ts)

Applied to files:

  • workspaces/mi/mi-visualizer/src/MainPanel.tsx
📚 Learning: 2025-11-25T06:34:10.812Z
Learnt from: CR
Repo: wso2/vscode-extensions PR: 0
File: workspaces/ballerina/component-diagram/AGENTS.md:0-0
Timestamp: 2025-11-25T06:34:10.812Z
Learning: Applies to workspaces/ballerina/component-diagram/src/components/nodes/EntryNode/EntryNodeWidget.tsx : Route EntryNode rendering to specialized widgets based on service type: use AIServiceWidget for 'ai:Service', GraphQLServiceWidget for 'graphql:Service', and GeneralWidget for HTTP and other services

Applied to files:

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

Applied to files:

  • workspaces/mi/mi-visualizer/src/utils/DSSResourceForm.ts
  • workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/SidePanelForms/QueryForm.tsx
  • workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/QueryServiceDesigner.tsx
📚 Learning: 2025-11-24T14:51:49.267Z
Learnt from: KCSAbeywickrama
Repo: wso2/vscode-extensions PR: 998
File: workspaces/ballerina/data-mapper/src/components/DataMapper/Header/ExpressionBar.tsx:113-132
Timestamp: 2025-11-24T14:51:49.267Z
Learning: In workspaces/ballerina/data-mapper/src/components/DataMapper/Header/ExpressionBar.tsx, if `textFieldRef.current` is not undefined, `textFieldRef.current.inputElement` is guaranteed to exist. If `inputElement` doesn't exist when `current` exists, it's a fatal error that should reach the error boundary rather than being handled with defensive null checks.

Applied to files:

  • workspaces/mi/mi-visualizer/src/utils/DSSResourceForm.ts
  • workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/QueryServiceDesigner.tsx
📚 Learning: 2025-11-20T11:04:33.712Z
Learnt from: KCSAbeywickrama
Repo: wso2/vscode-extensions PR: 898
File: workspaces/ballerina/data-mapper/src/components/DataMapper/SidePanel/QueryClauses/ClausesPanel.tsx:38-38
Timestamp: 2025-11-20T11:04:33.712Z
Learning: In workspaces/ballerina/data-mapper/src/components/DataMapper/SidePanel/QueryClauses/ClausesPanel.tsx, the use of `useDMQueryClausesPanelStore.getState()` to access `clauseToAdd` and `setClauseToAdd` (instead of the hook subscription pattern) is intentional to prevent re-renders when these state values change.

Applied to files:

  • workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/SidePanelForms/QueryForm.tsx
📚 Learning: 2025-11-25T06:34:10.812Z
Learnt from: CR
Repo: wso2/vscode-extensions PR: 0
File: workspaces/ballerina/component-diagram/AGENTS.md:0-0
Timestamp: 2025-11-25T06:34:10.812Z
Learning: Applies to workspaces/ballerina/component-diagram/src/components/nodes/EntryNode/components/GraphQLServiceWidget.tsx : For GraphQL services, group functions by type (Query, Subscription, Mutation) and allow independent expand/collapse of each group. Default state: Query group open, Subscription/Mutation groups collapsed

Applied to files:

  • workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/SidePanelForms/QueryForm.tsx
📚 Learning: 2025-11-25T06:34:10.812Z
Learnt from: CR
Repo: wso2/vscode-extensions PR: 0
File: workspaces/ballerina/component-diagram/AGENTS.md:0-0
Timestamp: 2025-11-25T06:34:10.812Z
Learning: Applies to workspaces/ballerina/component-diagram/src/components/DiagramContext.tsx : Use DiagramContext (React Context API) for state management across the diagram component, including expandedNodes and graphQLGroupOpen state

Applied to files:

  • workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/SidePanelForms/ResourceForm.tsx
  • workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/SidePanelForms/OperationForm.tsx
🧬 Code graph analysis (8)
workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/ResourceServiceDesigner.tsx (1)
workspaces/common-libs/ui-toolkit/src/components/Codicon/Codicon.tsx (1)
  • Codicon (44-56)
workspaces/mi/mi-extension/src/project-explorer/activate.ts (1)
workspaces/mi/mi-extension/src/stateMachine.ts (1)
  • openView (734-784)
workspaces/mi/mi-visualizer/src/utils/DSSResourceForm.ts (7)
workspaces/mi/syntax-tree/src/syntax-tree-interfaces.ts (2)
  • DSSQuery (1175-1179)
  • Range (59-62)
workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/SidePanelForms/QueryForm.tsx (2)
  • QueryType (89-89)
  • QueryFormData (91-93)
workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/SidePanelForms/ResourceForm.tsx (1)
  • ResourceFormData (108-110)
workspaces/mi/mi-rpc-client/src/RpcClient.ts (1)
  • RpcClient (30-137)
workspaces/mi/mi-visualizer/src/utils/template-engine/mustache-templates/templateUtils.ts (1)
  • getXML (44-83)
workspaces/mi/mi-visualizer/src/constants/index.ts (1)
  • DSS_TEMPLATES (65-76)
workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/SidePanelForms/OperationForm.tsx (1)
  • OperationFormData (95-97)
workspaces/mi/mi-visualizer/src/utils/template-engine/mustache-templates/templateUtils.ts (2)
workspaces/mi/mi-visualizer/src/constants/index.ts (1)
  • DSS_TEMPLATES (65-76)
workspaces/mi/mi-visualizer/src/utils/template-engine/mustache-templates/core/DSS.ts (6)
  • getEditQueryReferenceTemplate (69-71)
  • getAddQuery (37-41)
  • getAddFullQuery (43-47)
  • getQueryConfig (49-51)
  • getExpressionQuery (57-59)
  • getSQLQuery (53-55)
workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/SidePanelForms/QueryForm.tsx (4)
workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/SidePanelForms/OperationForm.tsx (3)
  • Container (45-49)
  • Title (51-57)
  • IconContainer (59-61)
workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/SidePanelForms/ResourceForm.tsx (3)
  • Container (45-49)
  • Title (51-57)
  • IconContainer (59-61)
workspaces/mi/mi-visualizer/src/constants/index.ts (1)
  • SIDE_PANEL_WIDTH (44-44)
workspaces/mi/mi-diagram/src/components/Form/common.ts (1)
  • openPopup (50-99)
workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/SidePanelForms/ResourceForm.tsx (3)
workspaces/ballerina/ballerina-visualizer/src/Context.tsx (1)
  • useVisualizerContext (134-134)
workspaces/common-libs/ui-toolkit/src/components/CheckBoxGroup/CheckBoxGroup.tsx (1)
  • FormCheckBox (141-167)
workspaces/mi/mi-diagram/src/components/Form/common.ts (1)
  • openPopup (50-99)
workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/QueryServiceDesigner.tsx (2)
workspaces/mi/mi-visualizer/src/utils/DSSResourceForm.ts (3)
  • generateQueryData (50-58)
  • onQueryCreate (122-153)
  • onQueryEdit (237-268)
workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/SidePanelForms/QueryForm.tsx (2)
  • QueryFormData (91-93)
  • QueryForm (103-212)
workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/SidePanelForms/OperationForm.tsx (3)
workspaces/ballerina/ballerina-visualizer/src/Context.tsx (1)
  • useVisualizerContext (134-134)
workspaces/common-libs/ui-toolkit/src/components/CheckBoxGroup/CheckBoxGroup.tsx (1)
  • FormCheckBox (141-167)
workspaces/mi/mi-diagram/src/components/Form/common.ts (1)
  • openPopup (50-99)
🪛 Biome (2.1.2)
workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/SidePanelForms/ResourceForm.tsx

[error] 96-96: Do not add then to an object.

(lint/suspicious/noThenProperty)

workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/QueryServiceDesigner.tsx

[error] 163-163: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.

The declaration is defined in this switch clause:

Safe fix: Wrap the declaration in a block.

(lint/correctness/noSwitchDeclarations)

workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/SidePanelForms/OperationForm.tsx

[error] 84-84: Do not add then to an object.

(lint/suspicious/noThenProperty)

🔇 Additional comments (22)
workspaces/mi/mi-extension/src/test/e2e-playwright-tests/components/ArtifactTest/DataService.ts (1)

70-72: LGTM! Consistent iframe label updates.

The iframe label updates from "Data Service Designer" to "Data Service Resource Designer" are consistent across all edit methods (editRDBMS, editMongoDB, editCassandraDB, editCsvDs, editCarbonDs), aligning with the view rename introduced in this PR.

Also applies to: 159-161, 295-297, 416-418, 517-519

workspaces/mi/syntax-tree/src/syntax-tree-interfaces.ts (1)

1175-1179: New DSSQuery interface looks good.

The interface extends STNode and includes the essential fields for query representation. The structure aligns with the template functions (getAddFullQuery, etc.) that reference name, datasource, and query.

workspaces/mi/mi-visualizer/src/views/Overview/ProjectStructureView.tsx (1)

130-137: LGTM! View reference updated correctly.

The dataServices entry now correctly references MACHINE_VIEW.DSSResourceServiceDesigner, consistent with the broader view rename across the PR.

workspaces/mi/mi-extension/src/project-explorer/activate.ts (1)

382-386: LGTM! Command handler updated to target the resource designer view.

The OPEN_DSS_SERVICE_DESIGNER command now correctly opens MACHINE_VIEW.DSSResourceServiceDesigner, aligning with the view restructuring in this PR.

workspaces/mi/mi-visualizer/src/utils/template-engine/mustache-templates/templateUtils.ts (2)

36-42: LGTM! New DSS template function imports.

The imports align with the new template cases added below and correspond to the functions defined in core/DSS.ts.


70-79: LGTM! New query template rendering cases.

The new cases correctly handle:

  • EDIT_QUERY_REFERENCE - for editing query references on resources/operations
  • ADD_FULL_QUERY - for creating complete queries with expression/SQL
  • UPDATE_QUERY_CONFIG - for updating query configuration (id, useConfig)
  • UPDATE_QUERY - conditional rendering based on data.isExpression flag

The conditional logic at line 79 correctly selects between expression and SQL templates based on the query type.

workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/ResourceServiceDesigner.tsx (3)

36-36: LGTM! Function export renamed appropriately.

The rename from DSSServiceDesignerView to DSSResourceServiceDesignerView clearly distinguishes this view as resource-focused, complementing the new query-focused DSSQueryServiceDesignerView.


237-245: LGTM! Query management navigation handler.

The handleManageQueries function correctly uses the RPC client to navigate to the DSSQueryServiceDesigner view, passing the current document URI for context.


321-324: LGTM! Header updates for query management.

The header title update to "Data Service Resource Designer" and the new "Manage Queries" button with the list-unordered icon provide clear navigation to the query management flow introduced in this PR.

workspaces/mi/mi-visualizer/src/MainPanel.tsx (2)

5-6: LGTM!

The new imports for DSSResourceServiceDesignerView and DSSQueryServiceDesignerView are correctly structured and follow the existing import pattern for form components.


380-385: LGTM!

The new switch cases for DSSResourceServiceDesigner and DSSQueryServiceDesigner are correctly implemented, following the same pattern as other designer views (e.g., line 212). The props syntaxTree and documentUri are appropriately passed to both components.

workspaces/mi/mi-visualizer/src/utils/template-engine/mustache-templates/core/DSS.ts (2)

43-59: LGTM!

The new template functions follow the existing patterns in this file. The conditional Mustache syntax for isExpression in getAddFullQuery() correctly handles both SQL and expression-based queries.


69-71: LGTM!

The getEditQueryReferenceTemplate() function correctly uses conditional self-closing syntax with {{#isSelfClosed}}.

workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/SidePanelForms/ResourceForm.tsx (3)

24-28: LGTM!

The new imports for form handling (Controller), query lookup (Keylookup), popup management (openPopup), and context access (useVisualizerContext) are correctly added to support the new query integration features.


71-89: LGTM!

The ResourceFields type and newResource defaults are correctly extended with queryId and useExistingQuery fields to support the new query association feature.


94-104: The Biome warning is a false positive.

The static analysis tool flags the .then() method in the yup schema, but this is the correct API for yup.string().when() conditional validation—not a Promise then property.

workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/QueryServiceDesigner.tsx (2)

30-41: LGTM!

The component structure with proper state initialization for query management follows React best practices with functional components and hooks.


57-68: LGTM!

The safe access pattern query.sql?.value ?? query.expression?.value ?? "" correctly handles both SQL and expression-based queries, preventing null reference errors.

workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/SidePanelForms/OperationForm.tsx (3)

24-28: LGTM!

The new imports correctly support the query integration feature, consistent with the parallel changes in ResourceForm.tsx.


64-78: LGTM!

The OperationFields type and newOperation defaults are correctly extended with queryId and useExistingQuery fields, mirroring the ResourceForm implementation.


80-91: The Biome warning is a false positive.

Similar to ResourceForm.tsx, the static analysis tool incorrectly flags the .then() method in the yup conditional validation schema.

workspaces/mi/mi-visualizer/src/utils/DSSResourceForm.ts (1)

171-171: Verify template handles undefined queryId.

data.queryId may be undefined if it's an optional field on the data object, and passing it directly to the EDIT_QUERY_REFERENCE template could cause issues. Ensure the template handles undefined values gracefully, or add a guard to validate queryId is present before using it.

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

♻️ Duplicate comments (6)
workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/SidePanelForms/ResourceForm.tsx (1)

265-283: Incorrect popup view for Query ID lookup.

The Keylookup is configured with filterType='dssQuery' for selecting a Query ID, but onCreateButtonClick opens a "datasource" popup. Since allowItemCreate={false}, the onCreateButtonClick handler is never invoked and should be removed to avoid confusion.

                             <Keylookup
                                 value={field.value}
                                 filterType='dssQuery'
                                 label="Query ID"
                                 allowItemCreate={false}
-                                onCreateButtonClick={(fetchItems: any, handleValueChange: any) => {
-                                    openPopup(rpcClient, "datasource", fetchItems, handleValueChange, documentUri, { datasource: undefined });
-                                }}
                                 onValueChange={field.onChange}
                                 required={true}
                             />
workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/SidePanelForms/OperationForm.tsx (1)

178-196: Incorrect popup view for Query ID lookup.

Same issue as in ResourceForm: the Keylookup is for "Query ID" with filterType='dssQuery', but onCreateButtonClick opens a "datasource" popup. Since allowItemCreate={false}, remove the unused handler.

                         <Keylookup
                             value={field.value}
                             filterType='dssQuery'
                             label="Query ID"
                             allowItemCreate={false}
-                            onCreateButtonClick={(fetchItems: any, handleValueChange: any) => {
-                                openPopup(rpcClient, "datasource", fetchItems, handleValueChange, documentUri, { datasource: undefined });
-                            }}
                             onValueChange={field.onChange}
                             required={true}
                         />
workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/QueryServiceDesigner.tsx (2)

160-174: Wrap switch case declaration in a block to prevent scope leakage.

The let dbName declaration inside the switch case can be accessed by other cases. As flagged by static analysis, wrap the case body in a block.

     const handleQueryCreate = (formData: QueryFormData) => {
         switch (formData.mode) {
-            case "create":
-                let dbName = "";
+            case "create": {
+                let dbName = "";
                 if (syntaxTree.data.configs !== undefined && syntaxTree.data.configs !== null && syntaxTree.data.configs.length > 0) {
                     dbName = syntaxTree.data.configs[0].id;
                 }
                 onQueryCreate(formData, queryBodyRange, documentUri, rpcClient, dbName);
                 break;
+            }
             case "edit":
                 onQueryEdit(formData, selectedQuery, documentUri, rpcClient);
                 break;
         }
         setQueryFormOpen(false);
     };

220-226: Conditional formData prop evaluates to boolean instead of undefined.

The expression mode === "edit" && formData evaluates to false when mode !== "edit", not undefined. This could cause type issues if QueryForm expects QueryType | undefined.

             <QueryForm
                 isOpen={isQueryFormOpen}
-                formData={mode === "edit" && formData}
+                formData={mode === "edit" ? formData : undefined}
                 onCancel={handleCancel}
                 documentUri={documentUri}
                 onSave={handleQueryCreate}
             />
workspaces/mi/mi-visualizer/src/utils/DSSResourceForm.ts (2)

62-63: Handle undefined in addition to empty string for queryId.

queryId is typed as string | undefined (optional field), but the check only handles empty string. Use a truthy check instead.

-    const queryName = data.queryId !== "" ? data.queryId :data.resourceMethod.toLowerCase() + "_" + data.resourcePath.replace(/[^a-zA-Z]/g, '').toLowerCase() + "_query";
-    const shouldCreateQuery = data.queryId === "";
+    const queryName = data.queryId ? data.queryId : data.resourceMethod.toLowerCase() + "_" + data.resourcePath.replace(/[^a-zA-Z]/g, '').toLowerCase() + "_query";
+    const shouldCreateQuery = !data.queryId;

94-95: Same undefined check issue for queryId in operation create.

-    const queryName = data.queryId !== "" ? data.queryId : data.operationName.replace(/[^a-zA-Z]/g, '').toLowerCase() + "_query";
-    const shouldCreateQuery = data.queryId === "";
+    const queryName = data.queryId ? data.queryId : data.operationName.replace(/[^a-zA-Z]/g, '').toLowerCase() + "_query";
+    const shouldCreateQuery = !data.queryId;
🧹 Nitpick comments (7)
workspaces/mi/mi-diagram/src/components/Form/common.ts (1)

142-148: Clarify key/value derivation and avoid magic indices for Query rows

The new logic is understandable but a bit brittle:

  • key can become undefined when keyIndex is out of bounds, with no fallback to index + 1.
  • The special case (key === "Query" && valueIndex == 4) hard‑codes both a label and column indices (1 and 4), which couples this helper tightly to a specific table layout.

To make this more robust and self‑documenting, consider:

  • Guarding keyIndex against value.length.
  • Normalizing the “raw” key and value via intermediate variables.
  • Centralizing the “Query uses column 1 when caller passes 4” rule so it’s easier to find and adjust later.

For example:

-        if (typeof value === 'object' && value !== null) {
-            const paramValues = getParamValues(value);
-            const key = keyIndex != undefined && keyIndex >= 0 ? typeof value[keyIndex] === 'object' ? value[keyIndex].value : value[keyIndex] : index + 1;
-            return {
-                id: index,
-                key: key,
-                value: (key === "Query" && valueIndex == 4) ? (typeof value[1] === 'object' ? value[1].value : value[1]) : 
-                (typeof value[valueIndex] === 'object' ? value[valueIndex].value : value[valueIndex]),
-                paramValues
-            };
+        if (typeof value === 'object' && value !== null) {
+            const paramValues = getParamValues(value);
+
+            const rawKey =
+                keyIndex != null && keyIndex >= 0 && keyIndex < value.length
+                    ? value[keyIndex]
+                    : index + 1;
+            const key = typeof rawKey === 'object' ? rawKey.value : rawKey;
+
+            const effectiveValueIndex =
+                key === 'Query' && valueIndex === 4 ? 1 : valueIndex;
+            const rawValue = value[effectiveValueIndex];
+            const normalizedValue =
+                typeof rawValue === 'object' ? rawValue.value : rawValue;
+
+            return {
+                id: index,
+                key,
+                value: normalizedValue,
+                paramValues,
+            };

This keeps the behavior but makes the implicit contract with Query rows explicit and adds a safer default for key.

workspaces/mi/mi-diagram/src/components/nodes/ReferenceNode/ReferenceNodeModel.ts (1)

53-64: View target updated correctly.

The method now opens MACHINE_VIEW.DSSResourceServiceDesigner instead of the removed DSSServiceDesigner enum value, aligning with the refactored designer views.

Note: The method name openDSSServiceDesigner could be updated to openDSSResourceServiceDesigner for consistency, but this is optional and can be deferred.

workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/QueryServiceDesigner.tsx (2)

43-95: Consider extracting getQueries outside the component.

The getQueries function is recreated on every render. Since it depends on highlightCode, handleDelete, and other handlers, consider using useCallback or restructuring to avoid unnecessary recreations.


130-139: Unused variable queryIndex in openDiagram.

The queryIndex variable is computed but never used.

     const openDiagram = (query: Resource) => {
-        const queryIndex = queryServiceModel.resources.findIndex((res) => res === query);
         const href = query.path;

         if (!href) {
             rpcClient.getMiDiagramRpcClient().showErrorMessage({ message: "Cannot find the query for selected resource" });
             return;
         }
         rpcClient.getMiVisualizerRpcClient().openView({ type: EVENT_TYPE.OPEN_VIEW, location: { view: MACHINE_VIEW.DataServiceView, documentUri: documentUri, identifier: href } })
     }
workspaces/mi/mi-visualizer/src/utils/DSSResourceForm.ts (3)

122-153: Missing error handling for the async query creation flow.

The promise chain in onQueryCreate lacks error handling. If getQueryType or applyEdit fails, the error will be silently swallowed.

     getQueryType(rpcClient, documentUri, data.datasource)
         .then((queryType) => {
             const queryContent = getXML(DSS_TEMPLATES.ADD_FULL_QUERY, {
                 ...formValues,
                 isExpression: queryType === "expression"
             });

             return rpcClient.getMiDiagramRpcClient().applyEdit({
                 text: queryContent,
                 documentUri,
                 range: {
                     start: {
                         line: range.end.line,
                         character: range.end.character,
                     },
                     end: {
                         line: range.end.line,
                         character: range.end.character,
                     }
                 }
             });
-        });
+        })
+        .catch((error) => {
+            console.error("Failed to create query:", error);
+        });

237-268: Missing error handling and similar pattern in onQueryEdit.

Same concern as onQueryCreate - the promise chain lacks error handling. Consider adding .catch() to handle potential failures gracefully.


270-285: Consider using find instead of forEach for early exit.

The getQueryType function iterates through all datasources even after finding a match. Using find would be more efficient and idiomatic.

 async function getQueryType(rpcClient: RpcClient, documentUri: string, datasource: string): Promise<string> {
-    let queryType = "sql";
     const existingDataService = await rpcClient.getMiDiagramRpcClient().getDataService({ path: documentUri });
-    existingDataService.datasources.forEach((ds) => {
-        if (ds.dataSourceName === datasource) {
-            const propertyKeys: string[] = [];
-            ds.datasourceProperties.forEach((attr: any) => {
-                propertyKeys.push(attr.key);
-            });
-            if (propertyKeys.includes("mongoDB_servers")) {
-                queryType = "expression";
-            }
-        }
-    });
-    return queryType;
+    const matchingDs = existingDataService.datasources.find((ds) => ds.dataSourceName === datasource);
+    if (matchingDs) {
+        const propertyKeys = matchingDs.datasourceProperties.map((attr: any) => attr.key);
+        if (propertyKeys.includes("mongoDB_servers")) {
+            return "expression";
+        }
+    }
+    return "sql";
 }
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 017146a and 2b8ab98.

📒 Files selected for processing (20)
  • workspaces/common-libs/service-designer/src/definitions.ts (1 hunks)
  • workspaces/mi/mi-core/src/state-machine-types.ts (1 hunks)
  • workspaces/mi/mi-diagram/src/components/Form/common.ts (1 hunks)
  • workspaces/mi/mi-diagram/src/components/nodes/ReferenceNode/ReferenceNodeModel.ts (1 hunks)
  • workspaces/mi/mi-diagram/src/components/sidePanel/dataServices/query.tsx (3 hunks)
  • workspaces/mi/mi-extension/src/project-explorer/activate.ts (1 hunks)
  • workspaces/mi/mi-extension/src/test/e2e-playwright-tests/components/ArtifactTest/DataService.ts (5 hunks)
  • workspaces/mi/mi-visualizer/src/MainPanel.tsx (2 hunks)
  • workspaces/mi/mi-visualizer/src/constants/index.ts (1 hunks)
  • workspaces/mi/mi-visualizer/src/utils/DSSResourceForm.ts (11 hunks)
  • workspaces/mi/mi-visualizer/src/utils/template-engine/mustache-templates/core/DSS.ts (1 hunks)
  • workspaces/mi/mi-visualizer/src/utils/template-engine/mustache-templates/templateUtils.ts (2 hunks)
  • workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/MainPanelForms/index.tsx (1 hunks)
  • workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/QueryServiceDesigner.tsx (1 hunks)
  • workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/ResourceServiceDesigner.tsx (5 hunks)
  • workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/SidePanelForms/OperationForm.tsx (5 hunks)
  • workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/SidePanelForms/QueryForm.tsx (1 hunks)
  • workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/SidePanelForms/ResourceForm.tsx (5 hunks)
  • workspaces/mi/mi-visualizer/src/views/Overview/ProjectStructureView.tsx (1 hunks)
  • workspaces/mi/syntax-tree/src/syntax-tree-interfaces.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (7)
  • workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/MainPanelForms/index.tsx
  • workspaces/mi/mi-diagram/src/components/sidePanel/dataServices/query.tsx
  • workspaces/common-libs/service-designer/src/definitions.ts
  • workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/SidePanelForms/QueryForm.tsx
  • workspaces/mi/mi-extension/src/project-explorer/activate.ts
  • workspaces/mi/syntax-tree/src/syntax-tree-interfaces.ts
  • workspaces/mi/mi-visualizer/src/utils/template-engine/mustache-templates/templateUtils.ts
🧰 Additional context used
🧠 Learnings (15)
📚 Learning: 2025-11-25T06:34:10.812Z
Learnt from: CR
Repo: wso2/vscode-extensions PR: 0
File: workspaces/ballerina/component-diagram/AGENTS.md:0-0
Timestamp: 2025-11-25T06:34:10.812Z
Learning: Applies to workspaces/ballerina/component-diagram/src/components/nodes/**/*.{ts,tsx} : Each node type must have a Model class extending NodeModel, a Factory class implementing the factory pattern, and a Widget React component for visual representation

Applied to files:

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

Applied to files:

  • workspaces/mi/mi-diagram/src/components/nodes/ReferenceNode/ReferenceNodeModel.ts
  • workspaces/mi/mi-diagram/src/components/Form/common.ts
  • workspaces/mi/mi-visualizer/src/MainPanel.tsx
  • workspaces/mi/mi-visualizer/src/views/Overview/ProjectStructureView.tsx
  • workspaces/mi/mi-visualizer/src/constants/index.ts
  • workspaces/mi/mi-extension/src/test/e2e-playwright-tests/components/ArtifactTest/DataService.ts
📚 Learning: 2025-11-25T06:34:10.812Z
Learnt from: CR
Repo: wso2/vscode-extensions PR: 0
File: workspaces/ballerina/component-diagram/AGENTS.md:0-0
Timestamp: 2025-11-25T06:34:10.812Z
Learning: Applies to workspaces/ballerina/component-diagram/src/components/**/*.tsx : Use React 18.2.0 features including concurrent rendering and automatic batching; avoid class components in favor of functional components with hooks

Applied to files:

  • workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/QueryServiceDesigner.tsx
  • workspaces/mi/mi-visualizer/src/MainPanel.tsx
📚 Learning: 2025-11-24T14:51:49.267Z
Learnt from: KCSAbeywickrama
Repo: wso2/vscode-extensions PR: 998
File: workspaces/ballerina/data-mapper/src/components/DataMapper/Header/ExpressionBar.tsx:113-132
Timestamp: 2025-11-24T14:51:49.267Z
Learning: In workspaces/ballerina/data-mapper/src/components/DataMapper/Header/ExpressionBar.tsx, if `textFieldRef.current` is not undefined, `textFieldRef.current.inputElement` is guaranteed to exist. If `inputElement` doesn't exist when `current` exists, it's a fatal error that should reach the error boundary rather than being handled with defensive null checks.

Applied to files:

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

Applied to files:

  • workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/QueryServiceDesigner.tsx
  • workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/SidePanelForms/OperationForm.tsx
  • workspaces/mi/mi-visualizer/src/utils/DSSResourceForm.ts
📚 Learning: 2025-11-25T06:34:10.812Z
Learnt from: CR
Repo: wso2/vscode-extensions PR: 0
File: workspaces/ballerina/component-diagram/AGENTS.md:0-0
Timestamp: 2025-11-25T06:34:10.812Z
Learning: Applies to workspaces/ballerina/component-diagram/src/resources/icons/**/*.tsx : Create separate SVG icon components in src/resources/icons/ for all diagram icons and import them as React components

Applied to files:

  • workspaces/mi/mi-visualizer/src/MainPanel.tsx
  • workspaces/mi/mi-visualizer/src/views/Overview/ProjectStructureView.tsx
📚 Learning: 2025-11-25T06:34:10.812Z
Learnt from: CR
Repo: wso2/vscode-extensions PR: 0
File: workspaces/ballerina/component-diagram/AGENTS.md:0-0
Timestamp: 2025-11-25T06:34:10.812Z
Learning: Applies to workspaces/ballerina/component-diagram/src/index.ts : Export the main Diagram component as the default export from the package entry point (index.ts)

Applied to files:

  • workspaces/mi/mi-visualizer/src/MainPanel.tsx
📚 Learning: 2025-11-25T06:34:10.812Z
Learnt from: CR
Repo: wso2/vscode-extensions PR: 0
File: workspaces/ballerina/component-diagram/AGENTS.md:0-0
Timestamp: 2025-11-25T06:34:10.812Z
Learning: Applies to workspaces/ballerina/component-diagram/src/components/nodes/EntryNode/EntryNodeWidget.tsx : Route EntryNode rendering to specialized widgets based on service type: use AIServiceWidget for 'ai:Service', GraphQLServiceWidget for 'graphql:Service', and GeneralWidget for HTTP and other services

Applied to files:

  • workspaces/mi/mi-visualizer/src/MainPanel.tsx
📚 Learning: 2025-11-25T06:34:10.812Z
Learnt from: CR
Repo: wso2/vscode-extensions PR: 0
File: workspaces/ballerina/component-diagram/AGENTS.md:0-0
Timestamp: 2025-11-25T06:34:10.812Z
Learning: Applies to workspaces/ballerina/component-diagram/src/components/DiagramContext.tsx : Use DiagramContext (React Context API) for state management across the diagram component, including expandedNodes and graphQLGroupOpen state

Applied to files:

  • workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/SidePanelForms/ResourceForm.tsx
  • workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/SidePanelForms/OperationForm.tsx
📚 Learning: 2025-11-26T07:49:56.428Z
Learnt from: KCSAbeywickrama
Repo: wso2/vscode-extensions PR: 653
File: workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/DataMapperUtils.ts:136-141
Timestamp: 2025-11-26T07:49:56.428Z
Learning: In workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/DataMapperUtils.ts, the goPrevViewBackButton() method is only called when in a focused view, ensuring breadcrumbs are always present. No guard for empty breadcrumbs is needed.

Applied to files:

  • workspaces/mi/mi-extension/src/test/e2e-playwright-tests/components/ArtifactTest/DataService.ts
📚 Learning: 2025-11-26T06:34:09.752Z
Learnt from: KCSAbeywickrama
Repo: wso2/vscode-extensions PR: 653
File: workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/DataMapperUtils.ts:128-134
Timestamp: 2025-11-26T06:34:09.752Z
Learning: In workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/DataMapperUtils.ts, the goPrevViewBreadcrumb() method is only called when in a focused view, ensuring breadcrumbs are always present. No guard for empty breadcrumbs is needed.

Applied to files:

  • workspaces/mi/mi-extension/src/test/e2e-playwright-tests/components/ArtifactTest/DataService.ts
📚 Learning: 2025-11-26T06:35:19.217Z
Learnt from: KCSAbeywickrama
Repo: wso2/vscode-extensions PR: 653
File: workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/DataMapperUtils.ts:173-178
Timestamp: 2025-11-26T06:35:19.217Z
Learning: In workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/DataMapperUtils.ts, the commented-out debugging block in the verifyFileContent function (lines 172-177 containing console.log, page.pause, and updateDataFileSync) is intentionally kept as a developer utility for updating test data files when needed. It should not be removed.

Applied to files:

  • workspaces/mi/mi-extension/src/test/e2e-playwright-tests/components/ArtifactTest/DataService.ts
📚 Learning: 2025-11-26T06:33:22.950Z
Learnt from: KCSAbeywickrama
Repo: wso2/vscode-extensions PR: 653
File: workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/DataMapperUtils.ts:86-112
Timestamp: 2025-11-26T06:33:22.950Z
Learning: In workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/DataMapperUtils.ts, empty catch blocks around progress ring waitForSelector calls (state: 'attached' and 'detached') are intentional. The progress ring duration depends on machine performance and may appear very briefly, causing the wait to miss the event. The try-catch allows the test to proceed gracefully regardless of timing.

Applied to files:

  • workspaces/mi/mi-extension/src/test/e2e-playwright-tests/components/ArtifactTest/DataService.ts
📚 Learning: 2025-11-25T06:34:10.812Z
Learnt from: CR
Repo: wso2/vscode-extensions PR: 0
File: workspaces/ballerina/component-diagram/AGENTS.md:0-0
Timestamp: 2025-11-25T06:34:10.812Z
Learning: Applies to workspaces/ballerina/component-diagram/src/**/*.test.{ts,tsx} : Create snapshot tests for all node widgets and verify visual consistency across renders

Applied to files:

  • workspaces/mi/mi-extension/src/test/e2e-playwright-tests/components/ArtifactTest/DataService.ts
📚 Learning: 2025-11-26T06:37:07.886Z
Learnt from: KCSAbeywickrama
Repo: wso2/vscode-extensions PR: 653
File: workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/dm-data/array-inner/inline/map3.bal.txt:6-8
Timestamp: 2025-11-26T06:37:07.886Z
Learning: In workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/dm-data/ directories, BAL test data files (such as those in array-inner/inline/, array-root/inline/, basic/inline/, and their reusable counterparts) may intentionally contain type errors and other violations. These are comparison files used to test data mapper functionality and error handling, so such errors should not be flagged as issues.

Applied to files:

  • workspaces/mi/mi-extension/src/test/e2e-playwright-tests/components/ArtifactTest/DataService.ts
🧬 Code graph analysis (4)
workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/SidePanelForms/ResourceForm.tsx (3)
workspaces/ballerina/ballerina-visualizer/src/Context.tsx (1)
  • useVisualizerContext (134-134)
workspaces/common-libs/ui-toolkit/src/components/CheckBoxGroup/CheckBoxGroup.tsx (1)
  • FormCheckBox (141-167)
workspaces/mi/mi-diagram/src/components/Form/common.ts (1)
  • openPopup (50-99)
workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/SidePanelForms/OperationForm.tsx (3)
workspaces/ballerina/ballerina-visualizer/src/Context.tsx (1)
  • useVisualizerContext (134-134)
workspaces/common-libs/ui-toolkit/src/components/CheckBoxGroup/CheckBoxGroup.tsx (1)
  • FormCheckBox (141-167)
workspaces/mi/mi-diagram/src/components/Form/common.ts (1)
  • openPopup (50-99)
workspaces/mi/mi-visualizer/src/utils/DSSResourceForm.ts (7)
workspaces/mi/syntax-tree/src/syntax-tree-interfaces.ts (2)
  • DSSQuery (1175-1179)
  • Range (59-62)
workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/SidePanelForms/QueryForm.tsx (2)
  • QueryType (89-89)
  • QueryFormData (91-93)
workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/SidePanelForms/ResourceForm.tsx (1)
  • ResourceFormData (108-110)
workspaces/mi/mi-rpc-client/src/RpcClient.ts (1)
  • RpcClient (30-137)
workspaces/mi/mi-visualizer/src/utils/template-engine/mustache-templates/templateUtils.ts (1)
  • getXML (44-83)
workspaces/mi/mi-visualizer/src/constants/index.ts (1)
  • DSS_TEMPLATES (65-76)
workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/SidePanelForms/OperationForm.tsx (1)
  • OperationFormData (95-97)
workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/ResourceServiceDesigner.tsx (1)
workspaces/common-libs/ui-toolkit/src/components/Codicon/Codicon.tsx (1)
  • Codicon (44-56)
🪛 Biome (2.1.2)
workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/QueryServiceDesigner.tsx

[error] 163-163: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.

The declaration is defined in this switch clause:

Safe fix: Wrap the declaration in a block.

(lint/correctness/noSwitchDeclarations)

workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/SidePanelForms/ResourceForm.tsx

[error] 96-96: Do not add then to an object.

(lint/suspicious/noThenProperty)

workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/SidePanelForms/OperationForm.tsx

[error] 84-84: Do not add then to an object.

(lint/suspicious/noThenProperty)

🔇 Additional comments (22)
workspaces/mi/mi-visualizer/src/constants/index.ts (1)

72-75: LGTM! New query management template constants added correctly.

The four new template action identifiers follow the existing naming conventions and support the new query management functionality introduced in this PR.

workspaces/mi/mi-extension/src/test/e2e-playwright-tests/components/ArtifactTest/DataService.ts (2)

70-72: LGTM! Test updated to reflect renamed designer view.

The iframe name correctly updated from "Data Service Designer" to "DSS Resource Designer" to align with the view renaming.


159-161: Consistent test updates across all edit methods.

All edit methods (editMongoDB, editCassandraDB, editCsvDs, editCarbonDs) consistently updated with the new iframe name.

Also applies to: 295-297, 416-418, 517-519

workspaces/mi/mi-visualizer/src/views/Overview/ProjectStructureView.tsx (1)

130-137: LGTM! Artifact type mapping updated correctly.

The dataServices artifact view correctly updated to use the new MACHINE_VIEW.DSSResourceServiceDesigner enum value.

workspaces/mi/mi-visualizer/src/MainPanel.tsx (2)

5-6: LGTM! Imports updated for refactored designer views.

The imports correctly reflect the renamed DSSResourceServiceDesignerView and newly added DSSQueryServiceDesignerView components.


380-385: New designer view cases added correctly.

The switch cases properly handle both the resource designer and the new query designer, following the existing pattern for other designer views. Props passed (syntaxTree and documentUri) are consistent with the component signatures.

workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/ResourceServiceDesigner.tsx (5)

36-36: Export renamed to reflect updated functionality.

The component export correctly renamed from DSSServiceDesignerView to DSSResourceServiceDesignerView, aligning with the focus on resource management. All import references have been updated accordingly.


51-106: QueryId extraction added to resources.

The queryId field is correctly extracted from resource.callQuery.href with a fallback to an empty string when callQuery is absent. This supports the new query reference functionality.


108-161: QueryId extraction added to operations.

The queryId field is correctly extracted from operation.callQuery.href with a fallback to an empty string, consistent with the resource extraction pattern.


237-245: LGTM! Manage Queries handler implemented correctly.

The handleManageQueries function properly opens the new DSS Query Service Designer view via RPC, passing the necessary documentUri context.


321-324: UI updated with Manage Queries button.

The header title correctly updated to "Data Service Resource Designer" and the new "Manage Queries" button added with appropriate icon and handler. The button placement and styling are consistent with other primary action buttons.

workspaces/mi/mi-visualizer/src/utils/template-engine/mustache-templates/core/DSS.ts (3)

43-47: LGTM! Full query template with conditional query type.

The getAddFullQuery function correctly returns a complete query template that conditionally renders either an <expression> or <sql> element based on the isExpression flag.


49-59: Query fragment templates added correctly.

The three new functions (getQueryConfig, getSQLQuery, getExpressionQuery) provide fine-grained query fragment templates for building/updating queries incrementally. This modular approach supports the new query editing workflows.


69-71: Query reference template with conditional self-closing.

The getEditQueryReferenceTemplate correctly generates a <call-query> element with conditional self-closing syntax based on the isSelfClosed flag.

workspaces/mi/mi-core/src/state-machine-types.ts (1)

68-69: Enum updated to support separate resource and query designers.

The MACHINE_VIEW enum replaces DSSServiceDesigner with two new members (DSSResourceServiceDesigner and DSSQueryServiceDesigner) to support refactored DSS designer views. Ensure all references to the removed DSSServiceDesigner have been updated across the codebase to prevent runtime errors.

workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/SidePanelForms/ResourceForm.tsx (2)

94-99: Yup conditional validation is correctly implemented.

The static analysis warning about then is a false positive - this is yup's standard API for conditional validation (.when() with then and otherwise callbacks), not a JavaScript Promise then property.


259-263: LGTM on the conditional checkbox rendering.

The "Use Existing Query" checkbox is correctly shown only when creating a new resource (no formData), allowing users to opt into selecting an existing query.

workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/SidePanelForms/OperationForm.tsx (2)

82-87: Yup conditional validation is correctly implemented.

The static analysis warning about then is a false positive - this is yup's .when() API for conditional validation.


172-176: LGTM on the conditional checkbox for existing query selection.

Correctly shows the checkbox only in create mode, consistent with ResourceForm.

workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/QueryServiceDesigner.tsx (1)

57-68: LGTM on the null-safe query value access.

The optional chaining with fallback (query.sql?.value ?? query.expression?.value ?? "") correctly handles both SQL and expression-based queries.

workspaces/mi/mi-visualizer/src/utils/DSSResourceForm.ts (2)

159-194: LGTM on the null-safe query reference handling.

The optional chaining for callQuery?.selfClosed and the conditional check for referenceQueryTagRange before applying edits correctly address the potential null reference issues.


201-234: LGTM on the operation edit null safety.

Same pattern as resource edit - properly handles undefined callQuery with optional chaining and conditional edit application.

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 adds a dedicated "Manage Queries" view to Data Services, enabling standalone query management separate from resource/operation creation. The Data Service Designer is split into two views: Resource Designer (for resources and operations) and Query Designer (for managing queries independently). This allows users to create, edit, and delete queries that can be referenced by resources and operations.

Key Changes

  • New Query Management System: Introduced a separate Query Designer view with dedicated QueryForm for creating and editing queries independently
  • Query Reference Support: Added queryId field to resources and operations, with conditional UI to use existing queries or create new ones during resource/operation creation
  • Template Engine Updates: Extended template system with new templates for full query creation, query configuration updates, and query reference editing

Reviewed changes

Copilot reviewed 20 out of 20 changed files in this pull request and generated 15 comments.

Show a summary per file
File Description
workspaces/mi/syntax-tree/src/syntax-tree-interfaces.ts Added queryId to DSSResource and DSSOperation interfaces; introduced new DSSQuery interface
workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/SidePanelForms/QueryForm.tsx New form component for standalone query creation and editing with datasource selection and query input
workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/SidePanelForms/ResourceForm.tsx Added queryId field with conditional validation and "Use Existing Query" checkbox for referencing queries
workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/SidePanelForms/OperationForm.tsx Added queryId field with conditional validation and "Use Existing Query" checkbox for referencing queries
workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/ResourceServiceDesigner.tsx Renamed from DSSServiceDesigner to DSSResourceServiceDesigner; added "Manage Queries" navigation button
workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/QueryServiceDesigner.tsx New designer view for query management with list, edit, delete, and highlight functionality
workspaces/mi/mi-visualizer/src/utils/DSSResourceForm.ts Added query creation/editing utilities with datasource type detection for SQL vs Expression queries
workspaces/mi/mi-visualizer/src/utils/template-engine/mustache-templates/core/DSS.ts Added templates for full query creation, query config updates, and query reference editing
workspaces/mi/mi-visualizer/src/utils/template-engine/mustache-templates/templateUtils.ts Integrated new query-related templates into template engine
workspaces/mi/mi-visualizer/src/constants/index.ts Added new DSS template constants for query operations
workspaces/mi/mi-visualizer/src/MainPanel.tsx Updated view routing to include both Resource and Query Designer views
workspaces/mi/mi-core/src/state-machine-types.ts Split DSSServiceDesigner into DSSResourceServiceDesigner and DSSQueryServiceDesigner views
workspaces/mi/mi-diagram/src/components/Form/common.ts Updated param manager logic to handle Query key-value extraction properly
workspaces/mi/mi-diagram/src/components/sidePanel/dataServices/query.tsx Fixed property name typos (forceJdbcBatchRequests → forceJDBCBatchRequests); removed queryId field
workspaces/mi/mi-extension/src/test/e2e-playwright-tests/components/ArtifactTest/DataService.ts Updated test references from "Data Service Designer" to "DSS Resource Designer"
Other files Updated view name references throughout the codebase for consistency
Comments suppressed due to low confidence (2)

workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/ResourceServiceDesigner.tsx:221

  • Avoid automated semicolon insertion (93% of all statements in the enclosing function have an explicit semicolon).
    workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/ResourceServiceDesigner.tsx:245
  • Avoid automated semicolon insertion (93% of all statements in the enclosing function have an explicit semicolon).

💡 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: 1

♻️ Duplicate comments (8)
workspaces/mi/mi-diagram/src/components/Form/common.ts (1)

163-163: Address the icon property inconsistency flagged in previous review.

As noted in the previous review, param.icon = 'query' is set here but the icon property is not included in the return object of getParamManagerFromValues (lines 143-149). This inconsistency suggests the icon may be either:

  1. Unused and should be removed from line 163, or
  2. Required elsewhere and should be added to the return object in getParamManagerFromValues

Please verify the icon property's usage and ensure consistency across both functions.

Run this script to check icon property usage:

#!/bin/bash
# Description: Check usage of icon property in param objects

# Search for icon property access in param-related code
rg -nP --type=ts -C3 'param\.icon|paramValues.*icon' 
workspaces/mi/mi-diagram/src/components/sidePanel/dataServices/query.tsx (1)

96-96: Critical: values.queryId is undefined - queryId field missing from form.

The code assigns values.queryId to updatedQuery.queryName, but the queryId input field was removed from the form UI. This will cause the query name to be undefined, breaking query updates. The same issue affects lines 151, 153, and 174 where values.queryId is also referenced.

Either restore the queryId field to the form (as suggested in the previous review), or refactor to use an alternative source for the query name, such as initialQueryName (line 54) if the query name should be immutable in this edit flow.

workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/SidePanelForms/ResourceForm.tsx (1)

259-283: Clean up Query ID Keylookup popup handler

The Keylookup for “Query ID” has:

  • allowItemCreate={false}, so the create action is unlikely to be exposed.
  • onCreateButtonClick calling openPopup(rpcClient, "dssQuery", …), but openPopup (per current implementation) doesn’t have a "dssQuery" case, so even if triggered it would no-op.

Given the new Manage Queries flow, this inline create path appears dead and may confuse future maintainers. Consider simplifying:

-    <Keylookup
-        value={field.value}
-        filterType='dssQuery'
-        label="Query ID"
-        allowItemCreate={false}
-        onCreateButtonClick={(fetchItems: any, handleValueChange: any) => {
-            openPopup(rpcClient, "dssQuery", fetchItems, handleValueChange, documentUri, { datasource: undefined });
-        }}
-        onValueChange={field.onChange}
-        required={true}
-    />
+    <Keylookup
+        value={field.value}
+        filterType='dssQuery'
+        label="Query ID"
+        allowItemCreate={false}
+        onValueChange={field.onChange}
+        required={true}
+    />

If you later introduce a dedicated query-creation popup, you can reintroduce allowItemCreate and wire a supported view key.

workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/QueryServiceDesigner.tsx (2)

158-172: Wrap create/edit switch cases in blocks to satisfy lint and avoid scope leakage.

let dbName is declared directly under the "create" case, which triggers the noSwitchDeclarations lint and can make future edits error‑prone if additional cases are added. Wrap each case body in its own block and slightly simplify the configs check.

-    const handleQueryCreate = (formData: QueryFormData) => {
-        switch (formData.mode) {
-            case "create":
-                let dbName = "";
-                if (syntaxTree.data.configs !== undefined && syntaxTree.data.configs !== null && syntaxTree.data.configs.length > 0) {
-                    dbName = syntaxTree.data.configs[0].id;
-                }
-                onQueryCreate(formData, queryBodyRange, documentUri, rpcClient, dbName);
-                break;
-            case "edit":
-                onQueryEdit(formData, selectedQuery, documentUri, rpcClient);
-                break;
-        }
-        setQueryFormOpen(false);
-    };
+    const handleQueryCreate = (formData: QueryFormData) => {
+        switch (formData.mode) {
+            case "create": {
+                let dbName = "";
+                if (syntaxTree.data.configs && syntaxTree.data.configs.length > 0) {
+                    dbName = syntaxTree.data.configs[0].id;
+                }
+                onQueryCreate(formData, queryBodyRange, documentUri, rpcClient, dbName);
+                break;
+            }
+            case "edit": {
+                onQueryEdit(formData, selectedQuery, documentUri, rpcClient);
+                break;
+            }
+        }
+        setQueryFormOpen(false);
+    };

218-224: Pass undefined (not false) to QueryForm when not editing.

mode === "edit" && formData evaluates to false when mode !== "edit", which can violate QueryForm’s type expectations and lead to confusing runtime checks.

-            <QueryForm
-                isOpen={isQueryFormOpen}
-                formData={mode === "edit" && formData}
-                onCancel={handleCancel}
-                documentUri={documentUri}
-                onSave={handleQueryCreate}
-            />
+            <QueryForm
+                isOpen={isQueryFormOpen}
+                formData={mode === "edit" ? formData : undefined}
+                onCancel={handleCancel}
+                documentUri={documentUri}
+                onSave={handleQueryCreate}
+            />
workspaces/mi/mi-visualizer/src/utils/DSSResourceForm.ts (2)

60-75: Fix queryId handling when it is undefined or empty.

Both onResourceCreate and onOperationCreate treat queryId !== "" as “has an id”. When queryId is undefined, this is true, so queryName becomes undefined and shouldCreateQuery is false, meaning you neither create a query nor generate a sensible default name.

Refactor to treat empty string/undefined uniformly:

 export const onResourceCreate = (data: ResourceFormData, range: Range, documentUri: string, rpcClient: RpcClient, dbName: string) => {
-
-    const queryName = data.queryId !== "" ? data.queryId : data.resourceMethod.toLowerCase() + "_" + data.resourcePath.replace(/[^a-zA-Z]/g, '').toLowerCase() + "_query";
-    const shouldCreateQuery = data.queryId === "";
+    const hasQueryId = !!data.queryId;
+    const queryName = hasQueryId
+        ? data.queryId!
+        : `${data.resourceMethod.toLowerCase()}_${data.resourcePath.replace(/[^a-zA-Z]/g, "").toLowerCase()}_query`;
+    const shouldCreateQuery = !hasQueryId;
@@
 export const onOperationCreate = (data: OperationFormData, range: Range, documentUri: string, rpcClient: RpcClient, dbName: string) => {
-
-    const queryName = data.queryId !== "" ? data.queryId : data.operationName.replace(/[^a-zA-Z]/g, '').toLowerCase() + "_query";
-    const shouldCreateQuery = data.queryId === "";
+    const hasQueryId = !!data.queryId;
+    const queryName = hasQueryId
+        ? data.queryId!
+        : `${data.operationName.replace(/[^a-zA-Z]/g, "").toLowerCase()}_query`;
+    const shouldCreateQuery = !hasQueryId;

This ensures both "" and undefined correctly trigger default-name generation and query creation.

Also applies to: 92-105


155-195: Query reference edit path now guards nulls correctly.

referenceQueryTagRange and isReferenceSelfClosed use optional chaining, and the final applyEdit calls for query references are wrapped in if (referenceQueryTagRange) blocks. This addresses the earlier null‑reference risks when callQuery is absent on a resource or operation.

Also applies to: 197-235

workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/SidePanelForms/OperationForm.tsx (1)

178-196: Remove or fix onCreateButtonClick for the Query ID Keylookup.

With allowItemCreate={false}, the create button is not exposed, and openPopup(rpcClient, "dssQuery", ...) currently targets a view type that openPopup doesn’t handle, so this handler is effectively dead and misleading.

If query creation from here is not supported, just drop the handler:

                         <Keylookup
                             value={field.value}
                             filterType='dssQuery'
                             label="Query ID"
                             allowItemCreate={false}
-                            onCreateButtonClick={(fetchItems: any, handleValueChange: any) => {
-                                openPopup(rpcClient, "dssQuery", fetchItems, handleValueChange, documentUri, { datasource: undefined });
-                            }}
                             onValueChange={field.onChange}
                             required={true}
                         />

If you plan to enable query creation later, consider adding a proper "query"/"dssQuery" case in openPopup at that time instead.

🧹 Nitpick comments (4)
workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/SidePanelForms/QueryForm.tsx (1)

141-152: Clarify Keylookup create behavior for Datasource

Keylookup is configured with allowItemCreate={false} but still receives an onCreateButtonClick that opens the datasource popup. If Keylookup hides the create action when allowItemCreate is false, this handler will never fire and just adds noise.

Consider either:

  • Removing onCreateButtonClick until you actually want inline datasource creation, or
  • Setting allowItemCreate to true once the UX is ready to support creating datasources from here.
workspaces/mi/mi-visualizer/src/utils/template-engine/mustache-templates/templateUtils.ts (1)

31-42: DSS query template routing is wired correctly

New DSS cases (edit reference, add full query, update config, update query) and their imports align with the helpers in core/DSS.ts and the DSS_TEMPLATES constants. The UPDATE_QUERY branch on data.isExpression cleanly separates <expression> vs <sql> output.

Also applies to: 70-79

workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/ResourceServiceDesigner.tsx (1)

237-245: Manage Queries entry point is well-integrated

handleManageQueries opens MACHINE_VIEW.DSSQueryServiceDesigner with the current documentUri, and the new “Manage Queries” primary button in the header makes this discoverable without disrupting existing resource/operation actions.

Also applies to: 321-324

workspaces/mi/mi-visualizer/src/utils/DSSResourceForm.ts (1)

122-153: onQueryCreate’s dbName parameter is unused – either wire it through or drop it.

onQueryCreate accepts dbName but only uses name, datasource, and query when rendering ADD_FULL_QUERY. If the template doesn’t need dbName, consider removing the parameter (and the call-site logic to compute it). If it does, pass it into getXML’s data object.

-export const onQueryCreate = (data: QueryFormData, range: Range, documentUri: string, rpcClient: RpcClient, dbName: string) => {
+export const onQueryCreate = (data: QueryFormData, range: Range, documentUri: string, rpcClient: RpcClient) => {
@@
-            const queryContent = getXML(DSS_TEMPLATES.ADD_FULL_QUERY, {
-                ...formValues,
-                isExpression: queryType === "expression"
-            });
+            const queryContent = getXML(DSS_TEMPLATES.ADD_FULL_QUERY, {
+                ...formValues,
+                isExpression: queryType === "expression",
+            });

(You’d also need to update the onQueryCreate call in QueryServiceDesigner.tsx accordingly.)

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2b8ab98 and 57d629f.

📒 Files selected for processing (20)
  • workspaces/common-libs/service-designer/src/definitions.ts (1 hunks)
  • workspaces/mi/mi-core/src/state-machine-types.ts (1 hunks)
  • workspaces/mi/mi-diagram/src/components/Form/common.ts (1 hunks)
  • workspaces/mi/mi-diagram/src/components/nodes/ReferenceNode/ReferenceNodeModel.ts (1 hunks)
  • workspaces/mi/mi-diagram/src/components/sidePanel/dataServices/query.tsx (3 hunks)
  • workspaces/mi/mi-extension/src/project-explorer/activate.ts (1 hunks)
  • workspaces/mi/mi-extension/src/test/e2e-playwright-tests/components/ArtifactTest/DataService.ts (5 hunks)
  • workspaces/mi/mi-visualizer/src/MainPanel.tsx (2 hunks)
  • workspaces/mi/mi-visualizer/src/constants/index.ts (1 hunks)
  • workspaces/mi/mi-visualizer/src/utils/DSSResourceForm.ts (11 hunks)
  • workspaces/mi/mi-visualizer/src/utils/template-engine/mustache-templates/core/DSS.ts (1 hunks)
  • workspaces/mi/mi-visualizer/src/utils/template-engine/mustache-templates/templateUtils.ts (2 hunks)
  • workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/MainPanelForms/index.tsx (1 hunks)
  • workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/QueryServiceDesigner.tsx (1 hunks)
  • workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/ResourceServiceDesigner.tsx (5 hunks)
  • workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/SidePanelForms/OperationForm.tsx (5 hunks)
  • workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/SidePanelForms/QueryForm.tsx (1 hunks)
  • workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/SidePanelForms/ResourceForm.tsx (5 hunks)
  • workspaces/mi/mi-visualizer/src/views/Overview/ProjectStructureView.tsx (1 hunks)
  • workspaces/mi/syntax-tree/src/syntax-tree-interfaces.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (7)
  • workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/MainPanelForms/index.tsx
  • workspaces/mi/mi-core/src/state-machine-types.ts
  • workspaces/mi/mi-visualizer/src/MainPanel.tsx
  • workspaces/mi/syntax-tree/src/syntax-tree-interfaces.ts
  • workspaces/mi/mi-visualizer/src/constants/index.ts
  • workspaces/common-libs/service-designer/src/definitions.ts
  • workspaces/mi/mi-visualizer/src/views/Overview/ProjectStructureView.tsx
🧰 Additional context used
🧠 Learnings (17)
📚 Learning: 2025-11-27T07:59:33.534Z
Learnt from: KCSAbeywickrama
Repo: wso2/vscode-extensions PR: 897
File: workspaces/ballerina/data-mapper/src/components/DataMapper/SidePanel/QueryClauses/ClausesPanel.tsx:50-59
Timestamp: 2025-11-27T07:59:33.534Z
Learning: In workspaces/ballerina/data-mapper/src/components/DataMapper/SidePanel/QueryClauses/ClausesPanel.tsx, the `clause.properties.expression` property in the `fillDefaults` function does not require defensive null/undefined checks because it's a required property enforced by form validation in ClauseEditor.

Applied to files:

  • workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/SidePanelForms/ResourceForm.tsx
  • workspaces/mi/mi-diagram/src/components/sidePanel/dataServices/query.tsx
  • workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/SidePanelForms/OperationForm.tsx
  • workspaces/mi/mi-visualizer/src/utils/DSSResourceForm.ts
  • workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/SidePanelForms/QueryForm.tsx
  • workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/QueryServiceDesigner.tsx
📚 Learning: 2025-11-25T06:34:10.812Z
Learnt from: CR
Repo: wso2/vscode-extensions PR: 0
File: workspaces/ballerina/component-diagram/AGENTS.md:0-0
Timestamp: 2025-11-25T06:34:10.812Z
Learning: Applies to workspaces/ballerina/component-diagram/src/components/DiagramContext.tsx : Use DiagramContext (React Context API) for state management across the diagram component, including expandedNodes and graphQLGroupOpen state

Applied to files:

  • workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/SidePanelForms/ResourceForm.tsx
  • workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/SidePanelForms/OperationForm.tsx
📚 Learning: 2025-11-20T11:04:33.712Z
Learnt from: KCSAbeywickrama
Repo: wso2/vscode-extensions PR: 898
File: workspaces/ballerina/data-mapper/src/components/DataMapper/SidePanel/QueryClauses/ClausesPanel.tsx:38-38
Timestamp: 2025-11-20T11:04:33.712Z
Learning: In workspaces/ballerina/data-mapper/src/components/DataMapper/SidePanel/QueryClauses/ClausesPanel.tsx, the use of `useDMQueryClausesPanelStore.getState()` to access `clauseToAdd` and `setClauseToAdd` (instead of the hook subscription pattern) is intentional to prevent re-renders when these state values change.

Applied to files:

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

Applied to files:

  • workspaces/mi/mi-diagram/src/components/Form/common.ts
  • workspaces/mi/mi-diagram/src/components/nodes/ReferenceNode/ReferenceNodeModel.ts
  • workspaces/mi/mi-extension/src/test/e2e-playwright-tests/components/ArtifactTest/DataService.ts
📚 Learning: 2025-11-25T06:34:10.812Z
Learnt from: CR
Repo: wso2/vscode-extensions PR: 0
File: workspaces/ballerina/component-diagram/AGENTS.md:0-0
Timestamp: 2025-11-25T06:34:10.812Z
Learning: Applies to workspaces/ballerina/component-diagram/src/components/nodes/**/*.{ts,tsx} : Each node type must have a Model class extending NodeModel, a Factory class implementing the factory pattern, and a Widget React component for visual representation

Applied to files:

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

Applied to files:

  • workspaces/mi/mi-diagram/src/components/nodes/ReferenceNode/ReferenceNodeModel.ts
📚 Learning: 2025-11-24T14:51:49.267Z
Learnt from: KCSAbeywickrama
Repo: wso2/vscode-extensions PR: 998
File: workspaces/ballerina/data-mapper/src/components/DataMapper/Header/ExpressionBar.tsx:113-132
Timestamp: 2025-11-24T14:51:49.267Z
Learning: In workspaces/ballerina/data-mapper/src/components/DataMapper/Header/ExpressionBar.tsx, if `textFieldRef.current` is not undefined, `textFieldRef.current.inputElement` is guaranteed to exist. If `inputElement` doesn't exist when `current` exists, it's a fatal error that should reach the error boundary rather than being handled with defensive null checks.

Applied to files:

  • workspaces/mi/mi-visualizer/src/utils/DSSResourceForm.ts
  • workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/QueryServiceDesigner.tsx
📚 Learning: 2025-11-25T06:34:10.812Z
Learnt from: CR
Repo: wso2/vscode-extensions PR: 0
File: workspaces/ballerina/component-diagram/AGENTS.md:0-0
Timestamp: 2025-11-25T06:34:10.812Z
Learning: Applies to workspaces/ballerina/component-diagram/src/components/Diagram.tsx : Implement proper error boundaries around the Diagram component to gracefully handle rendering errors without crashing the parent application

Applied to files:

  • workspaces/mi/mi-visualizer/src/utils/DSSResourceForm.ts
📚 Learning: 2025-11-25T06:34:10.812Z
Learnt from: CR
Repo: wso2/vscode-extensions PR: 0
File: workspaces/ballerina/component-diagram/AGENTS.md:0-0
Timestamp: 2025-11-25T06:34:10.812Z
Learning: Applies to workspaces/ballerina/component-diagram/src/**/*.{ts,tsx} : All async operations and promise handling in diagram utilities should use async/await syntax instead of .then() callbacks

Applied to files:

  • workspaces/mi/mi-visualizer/src/utils/DSSResourceForm.ts
📚 Learning: 2025-11-26T06:33:22.950Z
Learnt from: KCSAbeywickrama
Repo: wso2/vscode-extensions PR: 653
File: workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/DataMapperUtils.ts:86-112
Timestamp: 2025-11-26T06:33:22.950Z
Learning: In workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/DataMapperUtils.ts, empty catch blocks around progress ring waitForSelector calls (state: 'attached' and 'detached') are intentional. The progress ring duration depends on machine performance and may appear very briefly, causing the wait to miss the event. The try-catch allows the test to proceed gracefully regardless of timing.

Applied to files:

  • workspaces/mi/mi-visualizer/src/utils/DSSResourceForm.ts
  • workspaces/mi/mi-extension/src/test/e2e-playwright-tests/components/ArtifactTest/DataService.ts
📚 Learning: 2025-11-25T06:34:10.812Z
Learnt from: CR
Repo: wso2/vscode-extensions PR: 0
File: workspaces/ballerina/component-diagram/AGENTS.md:0-0
Timestamp: 2025-11-25T06:34:10.812Z
Learning: Applies to workspaces/ballerina/component-diagram/src/components/**/*.tsx : Use React 18.2.0 features including concurrent rendering and automatic batching; avoid class components in favor of functional components with hooks

Applied to files:

  • workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/SidePanelForms/QueryForm.tsx
  • workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/QueryServiceDesigner.tsx
📚 Learning: 2025-11-25T06:34:10.812Z
Learnt from: CR
Repo: wso2/vscode-extensions PR: 0
File: workspaces/ballerina/component-diagram/AGENTS.md:0-0
Timestamp: 2025-11-25T06:34:10.812Z
Learning: Applies to workspaces/ballerina/component-diagram/src/components/nodes/EntryNode/components/GraphQLServiceWidget.tsx : For GraphQL services, group functions by type (Query, Subscription, Mutation) and allow independent expand/collapse of each group. Default state: Query group open, Subscription/Mutation groups collapsed

Applied to files:

  • workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/SidePanelForms/QueryForm.tsx
📚 Learning: 2025-11-26T07:49:56.428Z
Learnt from: KCSAbeywickrama
Repo: wso2/vscode-extensions PR: 653
File: workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/DataMapperUtils.ts:136-141
Timestamp: 2025-11-26T07:49:56.428Z
Learning: In workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/DataMapperUtils.ts, the goPrevViewBackButton() method is only called when in a focused view, ensuring breadcrumbs are always present. No guard for empty breadcrumbs is needed.

Applied to files:

  • workspaces/mi/mi-extension/src/test/e2e-playwright-tests/components/ArtifactTest/DataService.ts
📚 Learning: 2025-11-26T06:34:09.752Z
Learnt from: KCSAbeywickrama
Repo: wso2/vscode-extensions PR: 653
File: workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/DataMapperUtils.ts:128-134
Timestamp: 2025-11-26T06:34:09.752Z
Learning: In workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/DataMapperUtils.ts, the goPrevViewBreadcrumb() method is only called when in a focused view, ensuring breadcrumbs are always present. No guard for empty breadcrumbs is needed.

Applied to files:

  • workspaces/mi/mi-extension/src/test/e2e-playwright-tests/components/ArtifactTest/DataService.ts
📚 Learning: 2025-11-26T06:35:19.217Z
Learnt from: KCSAbeywickrama
Repo: wso2/vscode-extensions PR: 653
File: workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/DataMapperUtils.ts:173-178
Timestamp: 2025-11-26T06:35:19.217Z
Learning: In workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/DataMapperUtils.ts, the commented-out debugging block in the verifyFileContent function (lines 172-177 containing console.log, page.pause, and updateDataFileSync) is intentionally kept as a developer utility for updating test data files when needed. It should not be removed.

Applied to files:

  • workspaces/mi/mi-extension/src/test/e2e-playwright-tests/components/ArtifactTest/DataService.ts
📚 Learning: 2025-11-25T06:34:10.812Z
Learnt from: CR
Repo: wso2/vscode-extensions PR: 0
File: workspaces/ballerina/component-diagram/AGENTS.md:0-0
Timestamp: 2025-11-25T06:34:10.812Z
Learning: Applies to workspaces/ballerina/component-diagram/src/**/*.test.{ts,tsx} : Create snapshot tests for all node widgets and verify visual consistency across renders

Applied to files:

  • workspaces/mi/mi-extension/src/test/e2e-playwright-tests/components/ArtifactTest/DataService.ts
📚 Learning: 2025-11-26T06:37:07.886Z
Learnt from: KCSAbeywickrama
Repo: wso2/vscode-extensions PR: 653
File: workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/dm-data/array-inner/inline/map3.bal.txt:6-8
Timestamp: 2025-11-26T06:37:07.886Z
Learning: In workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/dm-data/ directories, BAL test data files (such as those in array-inner/inline/, array-root/inline/, basic/inline/, and their reusable counterparts) may intentionally contain type errors and other violations. These are comparison files used to test data mapper functionality and error handling, so such errors should not be flagged as issues.

Applied to files:

  • workspaces/mi/mi-extension/src/test/e2e-playwright-tests/components/ArtifactTest/DataService.ts
🧬 Code graph analysis (6)
workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/SidePanelForms/ResourceForm.tsx (3)
workspaces/ballerina/ballerina-visualizer/src/Context.tsx (1)
  • useVisualizerContext (134-134)
workspaces/common-libs/ui-toolkit/src/components/CheckBoxGroup/CheckBoxGroup.tsx (1)
  • FormCheckBox (141-167)
workspaces/mi/mi-diagram/src/components/Form/common.ts (1)
  • openPopup (50-99)
workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/SidePanelForms/OperationForm.tsx (3)
workspaces/ballerina/ballerina-visualizer/src/Context.tsx (1)
  • useVisualizerContext (134-134)
workspaces/common-libs/ui-toolkit/src/components/CheckBoxGroup/CheckBoxGroup.tsx (1)
  • FormCheckBox (141-167)
workspaces/mi/mi-diagram/src/components/Form/common.ts (1)
  • openPopup (50-99)
workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/ResourceServiceDesigner.tsx (1)
workspaces/common-libs/ui-toolkit/src/components/Codicon/Codicon.tsx (1)
  • Codicon (44-56)
workspaces/mi/mi-visualizer/src/utils/DSSResourceForm.ts (4)
workspaces/mi/syntax-tree/src/syntax-tree-interfaces.ts (2)
  • DSSQuery (1175-1179)
  • Range (59-62)
workspaces/mi/mi-rpc-client/src/RpcClient.ts (1)
  • RpcClient (30-137)
workspaces/mi/mi-visualizer/src/utils/template-engine/mustache-templates/templateUtils.ts (1)
  • getXML (44-83)
workspaces/mi/mi-visualizer/src/constants/index.ts (1)
  • DSS_TEMPLATES (65-76)
workspaces/mi/mi-visualizer/src/utils/template-engine/mustache-templates/templateUtils.ts (2)
workspaces/mi/mi-visualizer/src/constants/index.ts (1)
  • DSS_TEMPLATES (65-76)
workspaces/mi/mi-visualizer/src/utils/template-engine/mustache-templates/core/DSS.ts (6)
  • getEditQueryReferenceTemplate (69-71)
  • getAddQuery (37-41)
  • getAddFullQuery (43-47)
  • getQueryConfig (49-51)
  • getExpressionQuery (57-59)
  • getSQLQuery (53-55)
workspaces/mi/mi-extension/src/project-explorer/activate.ts (1)
workspaces/mi/mi-extension/src/stateMachine.ts (1)
  • openView (734-784)
🪛 Biome (2.1.2)
workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/SidePanelForms/ResourceForm.tsx

[error] 96-96: Do not add then to an object.

(lint/suspicious/noThenProperty)

workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/SidePanelForms/OperationForm.tsx

[error] 84-84: Do not add then to an object.

(lint/suspicious/noThenProperty)

workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/QueryServiceDesigner.tsx

[error] 161-161: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.

The declaration is defined in this switch clause:

Safe fix: Wrap the declaration in a block.

(lint/correctness/noSwitchDeclarations)

🔇 Additional comments (13)
workspaces/mi/mi-diagram/src/components/sidePanel/dataServices/query.tsx (2)

71-72: Verify string comparison for boolean properties.

The boolean properties forceStoredProc and forceJDBCBatchRequests now use string comparison (=== "true"), while other boolean fields like returnGeneratedKeys (line 68) and returnUpdatedRowCount (line 70) use truthy checks. This inconsistency suggests these specific properties may be stored as strings in the data source.

Verify that this string comparison accurately reflects how these properties are persisted and retrieved from the XML/data source.

Note: The || false fallback is redundant since the === operator already returns a boolean.


326-332: LGTM - Consistent naming fix applied.

The camelCase correction from forceJdbcBatchRequests to forceJDBCBatchRequests is now consistent across the form reset (line 72), submit handler (line 92), controller name (line 326), and error handling (line 332).

workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/SidePanelForms/QueryForm.tsx (1)

44-105: Query form structure and validation look solid

Required fields, default values, and mode (create/edit) handling are consistent with ResourceForm and OperationForm. useEffect-based resets on isOpen + formData also look correct.

workspaces/mi/mi-extension/src/test/e2e-playwright-tests/components/ArtifactTest/DataService.ts (1)

70-73: Iframe target renames are consistent with the new DSS Resource Designer

All affected edit methods now switch to 'DSS Resource Designer' and throw matching error messages, which aligns with the updated view naming in the extension and visualizer.

Also applies to: 159-162, 295-298, 416-419, 517-520

workspaces/mi/mi-diagram/src/components/nodes/ReferenceNode/ReferenceNodeModel.ts (1)

53-64: Updated DSS view constant is correct

Routing to MACHINE_VIEW.DSSResourceServiceDesigner from ReferenceNodeModel matches the new view naming and keeps the “open designer” behavior intact.

workspaces/mi/mi-extension/src/project-explorer/activate.ts (1)

382-386: OPEN_DSS_SERVICE_DESIGNER now targets the correct view

Using MACHINE_VIEW.DSSResourceServiceDesigner here keeps the command in sync with the new DSS resource designer view; documentUri handling remains unchanged and correct.

workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/ResourceServiceDesigner.tsx (1)

51-80: Propagating queryId into service models looks correct

Deriving queryId from resource.callQuery?.href and operation.callQuery?.href exposes exactly what the new query flows need, without changing existing position/description semantics. This should integrate cleanly with generateResourceData / generateOperationData.

Also applies to: 108-135

workspaces/mi/mi-visualizer/src/utils/template-engine/mustache-templates/core/DSS.ts (1)

43-60: New DSS query templates are consistent and composable

getAddFullQuery, getQueryConfig, getSQLQuery, and getExpressionQuery all share the same { name, datasource, query, isExpression } contract and match how templateUtils.getXML consumes them. getEditQueryReferenceTemplate correctly toggles between <call-query href="..."> and a self-closed <call-query href="..." /> based on isSelfClosed.

Also applies to: 69-71

workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/SidePanelForms/ResourceForm.tsx (1)

91-104: Refactor queryId conditional schema to avoid Biome noThenProperty error

Biome flags the then key in the .when options as an error. You can keep the same behavior and satisfy the linter by switching to the callback-style when API instead of passing an options object:

-    queryId: yup.string().when("useExistingQuery", {
-        is: true,
-        then: (schema) =>
-        schema.required("Query ID is required"),
-        otherwise: (schema) => schema.notRequired(),
-    }),
+    queryId: yup.string().when("useExistingQuery", (useExisting, schema) =>
+        useExisting
+            ? schema.required("Query ID is required")
+            : schema.notRequired()
+    ),

This keeps queryId required only when useExistingQuery is true, but avoids defining a then property directly on the config object.

workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/QueryServiceDesigner.tsx (1)

43-95: Query extraction and edit/delete wiring look correct.

getQueries now safely handles both SQL and expression-based queries via query.sql?.value ?? query.expression?.value ?? "", and the generated currentQuery shape matches the DSSQuery fields consumed by generateQueryData. The actions (Go to Source / Edit / Delete) use the right object for each concern (syntax-tree query for edit/delete, ServiceDesigner resource for navigation).

workspaces/mi/mi-visualizer/src/utils/DSSResourceForm.ts (2)

26-58: Resource/operation/query data mapping looks consistent.

generateResourceData, generateOperationData, and generateQueryData correctly project syntax-tree models (DSSResource, DSSOperation, DSSQuery) into the respective form types, including the new queryId and returnRequestStatus fields. This should keep the forms and editors in sync with the syntax-tree layer.


237-287: Query edit flow and getQueryType logic look sound.

onQueryEdit correctly derives SQL vs expression ranges from either sql or expression tags, falls back to a sane default range, and uses getQueryType to drive the isExpression flag passed to UPDATE_QUERY. getQueryType’s datasource inspection via the mongoDB_servers key gives a clear pivot between SQL and expression queries.

workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/SidePanelForms/OperationForm.tsx (1)

64-91: Operation form integration with query fields looks coherent.

The new queryId and useExistingQuery fields, validation schema, and conditional rendering (watch("useExistingQuery")) are wired consistently with the existing react-hook-form setup. Editing vs creating mode is cleanly derived from formData and fed back via mode in OperationFormData.

Also applies to: 107-137, 150-177

Comment on lines +142 to +148
const key = keyIndex != undefined && keyIndex >= 0 ? typeof value[keyIndex] === 'object' ? value[keyIndex].value : value[keyIndex] : index + 1;
return {
id: index,
key: keyIndex != undefined && keyIndex >= 0 ? typeof value[keyIndex] === 'object' ? value[keyIndex].value : value[keyIndex] : index + 1,
value: typeof value[valueIndex] === 'object' ? value[valueIndex].value : value[valueIndex],
icon: 'query', paramValues
key: key,
value: (key === "Query" && valueIndex == 4) ? (typeof value[1] === 'object' ? value[1].value : value[1]) :
(typeof value[valueIndex] === 'object' ? value[valueIndex].value : value[valueIndex]),
paramValues
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 | 🟠 Major

Refactor special-case Query logic and extract magic values to constants.

The conditional logic at lines 146-147 introduces a hardcoded special case for "Query" with magic numbers (4 and 1) that lack explanation:

value: (key === "Query" && valueIndex == 4) ? (typeof value[1] === 'object' ? value[1].value : value[1]) : 
    (typeof value[valueIndex] === 'object' ? value[valueIndex].value : value[valueIndex])

Issues identified:

  • The string literal "Query" and numeric constants 4 and 1 are hardcoded without documentation
  • Using loose equality == instead of strict === for valueIndex comparison
  • No explanation for why Query requires different indexing logic (value[1] vs value[valueIndex])
  • This special case makes the function harder to maintain and understand

Based on learnings, constants should be defined in src/resources/constants.ts.

Consider this refactor:

Step 1: Define constants in src/resources/constants.ts:

export const QUERY_KEY = "Query";
export const QUERY_VALUE_INDEX = 4;
export const QUERY_ALTERNATIVE_INDEX = 1;

Step 2: Apply this diff:

+import { QUERY_KEY, QUERY_VALUE_INDEX, QUERY_ALTERNATIVE_INDEX } from '../../resources/constants';
+
 export const getParamManagerFromValues = (values: any[], keyIndex?: number, valueIndex: number = 1): any => {
     // ...
     const paramValues = values.map((value: any, index: number) => {
         if (typeof value === 'object' && value !== null) {
             const paramValues = getParamValues(value);
             const key = keyIndex != undefined && keyIndex >= 0 ? typeof value[keyIndex] === 'object' ? value[keyIndex].value : value[keyIndex] : index + 1;
+            // Special handling for Query key: use alternative index for value lookup
+            const shouldUseAlternativeIndex = key === QUERY_KEY && valueIndex === QUERY_VALUE_INDEX;
+            const valueIndexToUse = shouldUseAlternativeIndex ? QUERY_ALTERNATIVE_INDEX : valueIndex;
             return {
                 id: index,
                 key: key,
-                value: (key === "Query" && valueIndex == 4) ? (typeof value[1] === 'object' ? value[1].value : value[1]) : 
-                    (typeof value[valueIndex] === 'object' ? value[valueIndex].value : value[valueIndex]),
+                value: typeof value[valueIndexToUse] === 'object' ? value[valueIndexToUse].value : value[valueIndexToUse],
                 paramValues
             };
         }
     });
 }

Step 3: Add a comment or documentation explaining why Query keys require special indexing behavior.

🤖 Prompt for AI Agents
In workspaces/mi/mi-diagram/src/components/Form/common.ts around lines 142 to
148, replace the hardcoded special-case expression that checks for "Query" and
uses magic numbers (4 and 1) with a clear, constant-driven implementation:
import QUERY_KEY, QUERY_VALUE_INDEX, and QUERY_ALTERNATIVE_INDEX from
src/resources/constants.ts, use strict equality (===) for valueIndex comparison,
and select the alternate index via those constants instead of literals; also add
a brief inline comment explaining why the Query key requires the alternate
indexing behavior so future maintainers understand the exception.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant