-
Notifications
You must be signed in to change notification settings - Fork 60
Add a Manage Query view to Data Services #1030
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
|
Note Other AI code review bot(s) detectedCodeRabbit 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. WalkthroughThe 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; Changes
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
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes
Possibly related PRs
Suggested reviewers
Pre-merge checks and finishing touches❌ Failed checks (2 warnings)
✅ Passed checks (1 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
📜 Recent review detailsConfiguration used: CodeRabbit UI Review profile: CHILL Plan: Pro 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 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, accessingvalue[1]directly. This logic is fragile:
- Magic numbers: The values
4and1are hardcoded without explanation- No bounds checking: Accessing
value[1]without verifying array length- Unclear intent: Why does "Query" with valueIndex 4 need different handling?
Consider improving the code with:
- Add comments explaining the special case
- Add defensive checks for array access
- 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: Missingresetin useEffect dependency array.The
resetfunction fromuseFormis used inside the effect but not listed in the dependency array. Whileresetis 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
metaDataobject only containsmode, 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 unusedqueryIndexvariable.The
queryIndexvariable 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: Missingresetin useEffect dependency array.Similar to QueryForm, the
resetfunction 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
getQueryTypepromise chain doesn't handle rejections. IfgetDataServicefails 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 usingfindinstead offorEachfor cleaner code.The function iterates through all datasources even after finding a match. Using
findwith 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
📒 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.tsworkspaces/mi/mi-diagram/src/components/nodes/ReferenceNode/ReferenceNodeModel.tsworkspaces/mi/mi-visualizer/src/constants/index.tsworkspaces/mi/mi-visualizer/src/MainPanel.tsxworkspaces/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.tsworkspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/SidePanelForms/QueryForm.tsxworkspaces/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.tsworkspaces/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.tsxworkspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/SidePanelForms/OperationForm.tsxworkspaces/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.tsxworkspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/QueryServiceDesigner.tsxworkspaces/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.tsxworkspaces/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.tsxworkspaces/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
DSSResourceServiceDesignerinstead of the removedDSSServiceDesigner, 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
DSSResourceServiceDesignerview, 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_DESIGNERcommand now correctly opens theDSSResourceServiceDesignerview, 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
DSSResourceServiceDesignerbut 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
queryIdfield is added toDSSResource(line 1162) andDSSOperation(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 expectqueryIdto 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|| falseensures a boolean default.
91-92: Field name renamed consistently toforceJDBCBatchRequests.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 theonClickhandler.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, andUPDATE_QUERYare correctly implemented. The conditional rendering on line 79 appropriately selects between expression and SQL query templates based ondata.isExpression.workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/ResourceServiceDesigner.tsx (5)
36-36: Component renamed appropriately.The rename from
DSSServiceDesignerViewtoDSSResourceServiceDesignerViewclearly reflects the architectural split between resource and query management.
71-71:queryIdextraction with defensive null check.The optional chaining
resource.callQuery ? resource.callQuery.href : ""safely handles cases wherecallQuerymight be undefined, providing an empty string fallback.
124-124: Operation model extended withqueryIdconsistently.The same pattern used for resources is applied to operations, maintaining consistency across both resource types.
237-245: NewhandleManageQueriesfunction correctly opens the Query Designer view.The function properly uses
EVENT_TYPE.OPEN_VIEWand passes the requireddocumentUrito the newDSSQueryServiceDesignerview.
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
DSSResourceServiceDesignerViewand the newDSSQueryServiceDesignerViewfrom their respective module paths.
380-385: New view routing cases correctly implemented.Both
DSSResourceServiceDesignerandDSSQueryServiceDesignercases follow the established pattern, passingsyntaxTreeanddocumentUriprops. Thebreakstatements 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, anduseVisualizerContextare correctly added to support the new dynamic form fields and query selection.
64-78: NewqueryIdanduseExistingQueryfields 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 withthenproperty is the standard approach for conditional validation. The static analysis hint aboutnoThenPropertyis 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 whenuseExistingQueryis checked.
183-190: Potential mismatch:filterTypeisdssQuerybutopenPopupopens adatasourceview.The
Keylookupcomponent filters fordssQueryitems, but theonCreateButtonClickhandler callsopenPopup(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 theisExpressionflag using Mustache section syntax.
49-59: LGTM! Individual query component templates are well-structured.The
getQueryConfig,getSQLQuery, andgetExpressionQueryfunctions 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 theisSelfClosedflag.workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/SidePanelForms/QueryForm.tsx (1)
199-205: LGTM! Submit button correctly usesisDirtyfor 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
onCreateButtonClickhandler 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
generateQueryDatafunction provides a straightforward mapping from theDSSQuerymodel to the form-compatibleQueryType.
workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/QueryServiceDesigner.tsx
Show resolved
Hide resolved
workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/QueryServiceDesigner.tsx
Show resolved
Hide resolved
workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/QueryServiceDesigner.tsx
Show resolved
Hide resolved
824ce36 to
97d7018
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 4
♻️ 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 dbNamedeclaration 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: ConditionalformDataprop may cause unexpected behavior.The expression
mode === "edit" && formDataevaluates tofalse(a boolean) whenmode !== "edit", notundefined. This could cause type issues ifQueryFormexpectsQueryType | 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"andServiceDesigner = "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
dssprefix (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"(missingdss)UPDATE_QUERY→"update-query"(missingdss)EDIT_QUERY_REFERENCE→"edit-query-reference"(missingdss)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 ofany.Several state variables use
anytype which reduces type safety. Consider defining proper types forqueryBodyRange,formData, andselectedQueryto 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
Rangefrom the syntax-tree package andQueryTypefrom the QueryForm module.
130-139: Unused functionopenDiagrammay be dead code.The
openDiagramfunction is defined but only called fromhandleQueryClick. However, the variablequeryIndexon 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
Sectionnamespace andAddButtonWrapperstyled 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.
watchandsetValueare destructured fromuseFormbut 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
onQueryCreatedoesn't handle rejections. IfgetQueryTypeorapplyEditfails, 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: SimplifygetQueryTypeusing Array methods.The function can be simplified using
find()andsome()instead of nestedforEachloops.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
📒 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.tsxworkspaces/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.tsworkspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/SidePanelForms/QueryForm.tsxworkspaces/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.tsworkspaces/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.tsxworkspaces/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 onqueryIdaddition toDSSResource.The
queryIdfield correctly captures the query reference for resources, aligning with the extraction logic inResourceServiceDesigner.tsxwhere it's derived fromresource.callQuery.href.
1168-1173: LGTM onqueryIdaddition toDSSOperation.Consistent with the
DSSResourcechange, enabling query reference tracking for operations.
1175-1179: Verify ifDSSQueryinterface should include additional fields fromQuery.The new
DSSQueryinterface is minimal with onlyname,datasource, andqueryfields. The existingQueryinterface (lines 2007-2018) includes many additional fields likeparams,result,returnGeneratedKeys,sql,expression,useConfig, etc.If
DSSQueryis intended as a simplified UI/form model, consider adding a comment to clarify its purpose and relationship toQuery. 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.tsfor 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, andUPDATE_QUERY_CONFIGfollow the established patternUPDATE_QUERYcorrectly uses conditional logic to render either expression or SQL format based ondata.isExpressionworkspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/ResourceServiceDesigner.tsx (5)
36-36: LGTM on component rename.The rename from
DSSServiceDesignerViewtoDSSResourceServiceDesignerViewcorrectly reflects the split between resource-focused and query-focused designer views.
71-71: LGTM on queryId extraction for resources.Correctly extracts
queryIdfromresource.callQuery.hrefwith an empty string fallback whencallQueryis 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
DSSQueryServiceDesignerview using the RPC client with the currentdocumentUricontext.
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
thenproperty is a false positive. This is the standard yup conditional validation API using.when()withis,then, andotherwisecallbacks.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
isOpenandformDataprops, 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
queryIdanduseExistingQueryfields 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: NewgenerateQueryDatautility follows established patterns.The function correctly maps
DSSQuerymodel fields toQueryType, consistent withgenerateResourceDataandgenerateOperationData.
186-194: Null checks forreferenceQueryTagRangeproperly implemented.The conditional checks before applying query reference edits address the previously raised concerns about potential null references.
Also applies to: 225-233
workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/SidePanelForms/OperationForm.tsx
Show resolved
Hide resolved
workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/SidePanelForms/ResourceForm.tsx
Show resolved
Hide resolved
97d7018 to
017146a
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 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
Keylookupfor "Query ID" withfilterType='dssQuery'has anonCreateButtonClickhandler that opens a "datasource" popup, which is inconsistent with the field's purpose. SinceallowItemCreate={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 dbNamedeclaration 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: ConditionalformDataprop may cause unexpected behavior.The expression
mode === "edit" && formDataevaluates tofalse(a boolean) whenmode !== "edit", notundefined. This could cause type issues ifQueryFormexpectsQueryType | 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
Keylookupfor "Query ID" withfilterType='dssQuery'has anonCreateButtonClickhandler that opens a "datasource" popup, which is inconsistent with the field's purpose. SinceallowItemCreate={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 undefinedqueryIdin operation creation.Same issue as in
onResourceCreate: the code doesn't handleundefinedqueryId, 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 undefinedqueryIdin addition to empty string.The current code only checks for empty string (
""), butqueryIdis optional and could beundefined. Whenundefined, line 62 evaluatesundefined !== ""astrue, assigningundefinedtoqueryName, 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 makingqueryIdoptional onDSSResourceandDSSOperation.In
ResourceServiceDesigner.tsx,queryIdis derived asresource.callQuery ? resource.callQuery.href : "", suggesting that a query reference may not always be present. MakingqueryIdoptional (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
queryIdextraction 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 variablequeryIndex.The
queryIndexvariable 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.
AddButtonWrapperis 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: Includeresetin the useEffect dependency array.While
resetfrom 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
styleprop onSidePanelBodyis 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
getQueryTypepromise chain lacks error handling. IfgetQueryTypeorapplyEditfails, 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 ingetQueryType.The
getDataServiceRPC 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
📒 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.tsxworkspaces/mi/mi-extension/src/test/e2e-playwright-tests/components/ArtifactTest/DataService.tsworkspaces/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.tsxworkspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/SidePanelForms/QueryForm.tsxworkspaces/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.tsworkspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/SidePanelForms/QueryForm.tsxworkspaces/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.tsworkspaces/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.tsxworkspaces/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: NewDSSQueryinterface looks good.The interface extends
STNodeand includes the essential fields for query representation. The structure aligns with the template functions (getAddFullQuery, etc.) that referencename,datasource, andquery.workspaces/mi/mi-visualizer/src/views/Overview/ProjectStructureView.tsx (1)
130-137: LGTM! View reference updated correctly.The
dataServicesentry now correctly referencesMACHINE_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_DESIGNERcommand now correctly opensMACHINE_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/operationsADD_FULL_QUERY- for creating complete queries with expression/SQLUPDATE_QUERY_CONFIG- for updating query configuration (id, useConfig)UPDATE_QUERY- conditional rendering based ondata.isExpressionflagThe 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
DSSServiceDesignerViewtoDSSResourceServiceDesignerViewclearly distinguishes this view as resource-focused, complementing the new query-focusedDSSQueryServiceDesignerView.
237-245: LGTM! Query management navigation handler.The
handleManageQueriesfunction correctly uses the RPC client to navigate to theDSSQueryServiceDesignerview, 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-unorderedicon 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
DSSResourceServiceDesignerViewandDSSQueryServiceDesignerVieware correctly structured and follow the existing import pattern for form components.
380-385: LGTM!The new switch cases for
DSSResourceServiceDesignerandDSSQueryServiceDesignerare correctly implemented, following the same pattern as other designer views (e.g., line 212). The propssyntaxTreeanddocumentUriare 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
isExpressioningetAddFullQuery()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
ResourceFieldstype andnewResourcedefaults are correctly extended withqueryIdanduseExistingQueryfields 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 foryup.string().when()conditional validation—not a Promisethenproperty.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
OperationFieldstype andnewOperationdefaults are correctly extended withqueryIdanduseExistingQueryfields, mirroring theResourceFormimplementation.
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 undefinedqueryId.
data.queryIdmay be undefined if it's an optional field on the data object, and passing it directly to theEDIT_QUERY_REFERENCEtemplate could cause issues. Ensure the template handles undefined values gracefully, or add a guard to validatequeryIdis present before using it.
017146a to
2b8ab98
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 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
Keylookupis configured withfilterType='dssQuery'for selecting a Query ID, butonCreateButtonClickopens a "datasource" popup. SinceallowItemCreate={false}, theonCreateButtonClickhandler 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
Keylookupis for "Query ID" withfilterType='dssQuery', butonCreateButtonClickopens a "datasource" popup. SinceallowItemCreate={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 dbNamedeclaration 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: ConditionalformDataprop evaluates to boolean instead of undefined.The expression
mode === "edit" && formDataevaluates tofalsewhenmode !== "edit", notundefined. This could cause type issues ifQueryFormexpectsQueryType | 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: Handleundefinedin addition to empty string forqueryId.
queryIdis typed asstring | 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 forqueryIdin 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: Clarifykey/valuederivation and avoid magic indices for Query rowsThe new logic is understandable but a bit brittle:
keycan becomeundefinedwhenkeyIndexis out of bounds, with no fallback toindex + 1.- The special case
(key === "Query" && valueIndex == 4)hard‑codes both a label and column indices (1and4), which couples this helper tightly to a specific table layout.To make this more robust and self‑documenting, consider:
- Guarding
keyIndexagainstvalue.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.DSSResourceServiceDesignerinstead of the removedDSSServiceDesignerenum value, aligning with the refactored designer views.Note: The method name
openDSSServiceDesignercould be updated toopenDSSResourceServiceDesignerfor consistency, but this is optional and can be deferred.workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/QueryServiceDesigner.tsx (2)
43-95: Consider extractinggetQueriesoutside the component.The
getQueriesfunction is recreated on every render. Since it depends onhighlightCode,handleDelete, and other handlers, consider usinguseCallbackor restructuring to avoid unnecessary recreations.
130-139: Unused variablequeryIndexinopenDiagram.The
queryIndexvariable 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
onQueryCreatelacks error handling. IfgetQueryTypeorapplyEditfails, 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 inonQueryEdit.Same concern as
onQueryCreate- the promise chain lacks error handling. Consider adding.catch()to handle potential failures gracefully.
270-285: Consider usingfindinstead offorEachfor early exit.The
getQueryTypefunction iterates through all datasources even after finding a match. Usingfindwould 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
📒 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.tsworkspaces/mi/mi-diagram/src/components/Form/common.tsworkspaces/mi/mi-visualizer/src/MainPanel.tsxworkspaces/mi/mi-visualizer/src/views/Overview/ProjectStructureView.tsxworkspaces/mi/mi-visualizer/src/constants/index.tsworkspaces/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.tsxworkspaces/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.tsxworkspaces/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.tsxworkspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/SidePanelForms/OperationForm.tsxworkspaces/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.tsxworkspaces/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.tsxworkspaces/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.DSSResourceServiceDesignerenum value.workspaces/mi/mi-visualizer/src/MainPanel.tsx (2)
5-6: LGTM! Imports updated for refactored designer views.The imports correctly reflect the renamed
DSSResourceServiceDesignerViewand newly addedDSSQueryServiceDesignerViewcomponents.
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 (
syntaxTreeanddocumentUri) 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
DSSServiceDesignerViewtoDSSResourceServiceDesignerView, aligning with the focus on resource management. All import references have been updated accordingly.
51-106: QueryId extraction added to resources.The
queryIdfield is correctly extracted fromresource.callQuery.hrefwith a fallback to an empty string whencallQueryis absent. This supports the new query reference functionality.
108-161: QueryId extraction added to operations.The
queryIdfield is correctly extracted fromoperation.callQuery.hrefwith a fallback to an empty string, consistent with the resource extraction pattern.
237-245: LGTM! Manage Queries handler implemented correctly.The
handleManageQueriesfunction properly opens the new DSS Query Service Designer view via RPC, passing the necessarydocumentUricontext.
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
getAddFullQueryfunction correctly returns a complete query template that conditionally renders either an<expression>or<sql>element based on theisExpressionflag.
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
getEditQueryReferenceTemplatecorrectly generates a<call-query>element with conditional self-closing syntax based on theisSelfClosedflag.workspaces/mi/mi-core/src/state-machine-types.ts (1)
68-69: Enum updated to support separate resource and query designers.The
MACHINE_VIEWenum replacesDSSServiceDesignerwith two new members (DSSResourceServiceDesignerandDSSQueryServiceDesigner) to support refactored DSS designer views. Ensure all references to the removedDSSServiceDesignerhave 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
thenis a false positive - this is yup's standard API for conditional validation (.when()withthenandotherwisecallbacks), not a JavaScript Promisethenproperty.
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
thenis 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?.selfClosedand the conditional check forreferenceQueryTagRangebefore 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
callQuerywith optional chaining and conditional edit application.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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
queryIdfield 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.
workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/SidePanelForms/OperationForm.tsx
Show resolved
Hide resolved
workspaces/mi/mi-diagram/src/components/sidePanel/dataServices/query.tsx
Show resolved
Hide resolved
workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/QueryServiceDesigner.tsx
Outdated
Show resolved
Hide resolved
workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/SidePanelForms/ResourceForm.tsx
Show resolved
Hide resolved
workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/SidePanelForms/QueryForm.tsx
Outdated
Show resolved
Hide resolved
workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/SidePanelForms/QueryForm.tsx
Outdated
Show resolved
Hide resolved
workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/SidePanelForms/QueryForm.tsx
Outdated
Show resolved
Hide resolved
workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/SidePanelForms/QueryForm.tsx
Outdated
Show resolved
Hide resolved
workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/SidePanelForms/QueryForm.tsx
Outdated
Show resolved
Hide resolved
2b8ab98 to
57d629f
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 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 theiconproperty is not included in the return object ofgetParamManagerFromValues(lines 143-149). This inconsistency suggests the icon may be either:
- Unused and should be removed from line 163, or
- Required elsewhere and should be added to the return object in
getParamManagerFromValuesPlease 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.queryIdis undefined - queryId field missing from form.The code assigns
values.queryIdtoupdatedQuery.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 wherevalues.queryIdis 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 IDKeylookuppopup handlerThe
Keylookupfor “Query ID” has:
allowItemCreate={false}, so the create action is unlikely to be exposed.onCreateButtonClickcallingopenPopup(rpcClient, "dssQuery", …), butopenPopup(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
allowItemCreateand wire a supported view key.workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/QueryServiceDesigner.tsx (2)
158-172: Wrapcreate/editswitch cases in blocks to satisfy lint and avoid scope leakage.
let dbNameis declared directly under the"create"case, which triggers thenoSwitchDeclarationslint 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: Passundefined(notfalse) toQueryFormwhen not editing.
mode === "edit" && formDataevaluates tofalsewhenmode !== "edit", which can violateQueryForm’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: FixqueryIdhandling when it isundefinedor empty.Both
onResourceCreateandonOperationCreatetreatqueryId !== ""as “has an id”. WhenqueryIdisundefined, this istrue, soqueryNamebecomesundefinedandshouldCreateQueryisfalse, 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
""andundefinedcorrectly trigger default-name generation and query creation.Also applies to: 92-105
155-195: Query reference edit path now guards nulls correctly.
referenceQueryTagRangeandisReferenceSelfCloseduse optional chaining, and the finalapplyEditcalls for query references are wrapped inif (referenceQueryTagRange)blocks. This addresses the earlier null‑reference risks whencallQueryis 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 fixonCreateButtonClickfor the Query IDKeylookup.With
allowItemCreate={false}, the create button is not exposed, andopenPopup(rpcClient, "dssQuery", ...)currently targets a view type thatopenPopupdoesn’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 inopenPopupat that time instead.
🧹 Nitpick comments (4)
workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/SidePanelForms/QueryForm.tsx (1)
141-152: ClarifyKeylookupcreate behavior for Datasource
Keylookupis configured withallowItemCreate={false}but still receives anonCreateButtonClickthat opens the datasource popup. IfKeylookuphides the create action whenallowItemCreateisfalse, this handler will never fire and just adds noise.Consider either:
- Removing
onCreateButtonClickuntil you actually want inline datasource creation, or- Setting
allowItemCreatetotrueonce 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 correctlyNew DSS cases (edit reference, add full query, update config, update query) and their imports align with the helpers in
core/DSS.tsand theDSS_TEMPLATESconstants. TheUPDATE_QUERYbranch ondata.isExpressioncleanly 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
handleManageQueriesopensMACHINE_VIEW.DSSQueryServiceDesignerwith the currentdocumentUri, 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’sdbNameparameter is unused – either wire it through or drop it.
onQueryCreateacceptsdbNamebut only usesname,datasource, andquerywhen renderingADD_FULL_QUERY. If the template doesn’t needdbName, consider removing the parameter (and the call-site logic to compute it). If it does, pass it intogetXML’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
onQueryCreatecall inQueryServiceDesigner.tsxaccordingly.)
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 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.tsxworkspaces/mi/mi-diagram/src/components/sidePanel/dataServices/query.tsxworkspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/SidePanelForms/OperationForm.tsxworkspaces/mi/mi-visualizer/src/utils/DSSResourceForm.tsworkspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/SidePanelForms/QueryForm.tsxworkspaces/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.tsxworkspaces/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.tsxworkspaces/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.tsworkspaces/mi/mi-diagram/src/components/nodes/ReferenceNode/ReferenceNodeModel.tsworkspaces/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.tsworkspaces/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.tsworkspaces/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.tsxworkspaces/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
forceStoredProcandforceJDBCBatchRequestsnow use string comparison (=== "true"), while other boolean fields likereturnGeneratedKeys(line 68) andreturnUpdatedRowCount(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
|| falsefallback is redundant since the===operator already returns a boolean.
326-332: LGTM - Consistent naming fix applied.The camelCase correction from
forceJdbcBatchRequeststoforceJDBCBatchRequestsis 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 solidRequired fields, default values, and mode (
create/edit) handling are consistent withResourceFormandOperationForm.useEffect-based resets onisOpen+formDataalso 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 DesignerAll 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 correctRouting to
MACHINE_VIEW.DSSResourceServiceDesignerfromReferenceNodeModelmatches 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 viewUsing
MACHINE_VIEW.DSSResourceServiceDesignerhere keeps the command in sync with the new DSS resource designer view;documentUrihandling remains unchanged and correct.workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/ResourceServiceDesigner.tsx (1)
51-80: PropagatingqueryIdinto service models looks correctDeriving
queryIdfromresource.callQuery?.hrefandoperation.callQuery?.hrefexposes exactly what the new query flows need, without changing existing position/description semantics. This should integrate cleanly withgenerateResourceData/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, andgetExpressionQueryall share the same{ name, datasource, query, isExpression }contract and match howtemplateUtils.getXMLconsumes them.getEditQueryReferenceTemplatecorrectly toggles between<call-query href="...">and a self-closed<call-query href="..." />based onisSelfClosed.Also applies to: 69-71
workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/SidePanelForms/ResourceForm.tsx (1)
91-104: RefactorqueryIdconditional schema to avoid BiomenoThenPropertyerrorBiome flags the
thenkey in the.whenoptions as an error. You can keep the same behavior and satisfy the linter by switching to the callback-stylewhenAPI 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
queryIdrequired only whenuseExistingQueryis true, but avoids defining athenproperty 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.
getQueriesnow safely handles both SQL and expression-based queries viaquery.sql?.value ?? query.expression?.value ?? "", and the generatedcurrentQueryshape matches theDSSQueryfields consumed bygenerateQueryData. 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, andgenerateQueryDatacorrectly project syntax-tree models (DSSResource,DSSOperation,DSSQuery) into the respective form types, including the newqueryIdandreturnRequestStatusfields. This should keep the forms and editors in sync with the syntax-tree layer.
237-287: Query edit flow andgetQueryTypelogic look sound.
onQueryEditcorrectly derives SQL vs expression ranges from eithersqlorexpressiontags, falls back to a sane default range, and usesgetQueryTypeto drive theisExpressionflag passed toUPDATE_QUERY.getQueryType’s datasource inspection via themongoDB_serverskey 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
queryIdanduseExistingQueryfields, validation schema, and conditional rendering (watch("useExistingQuery")) are wired consistently with the existing react-hook-form setup. Editing vs creating mode is cleanly derived fromformDataand fed back viamodeinOperationFormData.Also applies to: 107-137, 150-177
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
UX / Validation
Templates
Tests
✏️ Tip: You can customize this high-level summary in your review settings.