diff --git a/common/config/rush/pnpm-lock.yaml b/common/config/rush/pnpm-lock.yaml index e483ed47f52..5157348b745 100644 --- a/common/config/rush/pnpm-lock.yaml +++ b/common/config/rush/pnpm-lock.yaml @@ -2108,8 +2108,8 @@ importers: version: 4.38.3 devDependencies: '@playwright/test': - specifier: ~1.52.0 - version: 1.52.0 + specifier: ~1.55.1 + version: 1.55.1 '@types/mocha': specifier: ^10.0.3 version: 10.0.10 @@ -2254,8 +2254,8 @@ importers: specifier: ^1.8.3 version: 1.9.4 '@playwright/test': - specifier: 1.52.0 - version: 1.52.0 + specifier: 1.55.1 + version: 1.55.1 '@types/byline': specifier: ^4.2.36 version: 4.2.36 @@ -2486,8 +2486,8 @@ importers: ../../workspaces/common-libs/playwright-vscode-tester: dependencies: '@playwright/test': - specifier: 1.52.0 - version: 1.52.0 + specifier: 1.55.1 + version: 1.55.1 '@vscode/vsce': specifier: ~3.4.2 version: 3.4.2 @@ -2504,8 +2504,8 @@ importers: specifier: ~1.2.0 version: 1.2.0 playwright-core: - specifier: ~1.52.0 - version: 1.52.0 + specifier: ~1.55.1 + version: 1.55.1 targz: specifier: ~1.0.1 version: 1.0.1 @@ -3345,8 +3345,8 @@ importers: version: 4.38.3 devDependencies: '@playwright/test': - specifier: ~1.52.0 - version: 1.52.0 + specifier: ~1.55.1 + version: 1.55.1 '@types/mocha': specifier: ^10.0.1 version: 10.0.10 @@ -3387,8 +3387,8 @@ importers: specifier: ^11.4.0 version: 11.7.1 playwright-core: - specifier: ~1.52.0 - version: 1.52.0 + specifier: ~1.55.1 + version: 1.55.1 rimraf: specifier: ~6.0.1 version: 6.0.1 @@ -3481,8 +3481,8 @@ importers: specifier: ^4.7.0 version: 4.7.0(monaco-editor@0.52.2)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) '@playwright/test': - specifier: 1.52.0 - version: 1.52.0 + specifier: 1.55.1 + version: 1.55.1 '@pmmmwh/react-refresh-webpack-plugin': specifier: ~0.6.0 version: 0.6.1(@types/webpack@5.28.5(webpack-cli@5.1.4))(react-refresh@0.11.0)(type-fest@4.41.0)(webpack-dev-server@5.2.2)(webpack-hot-middleware@2.26.1)(webpack@5.101.0) @@ -3812,8 +3812,8 @@ importers: specifier: ^1.9.4 version: 1.9.4 '@playwright/test': - specifier: 1.52.0 - version: 1.52.0 + specifier: 1.55.1 + version: 1.55.1 '@types/byline': specifier: ^4.2.36 version: 4.2.36 @@ -6059,8 +6059,8 @@ packages: resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} engines: {node: '>=14'} - '@playwright/test@1.52.0': - resolution: {integrity: sha512-uh6W7sb55hl7D6vsAeA+V2p5JnlAqzhqFyF0VcJkKZXkgnFcVG9PziERRHQfPLfNGx1C292a4JqbWzhR8L4R1g==} + '@playwright/test@1.55.1': + resolution: {integrity: sha512-IVAh/nOJaw6W9g+RJVlIQJ6gSiER+ae6mKQ5CX1bERzQgbC1VSeBlwdvczT7pxb0GWiyrxH4TGKbMfDb4Sq/ig==} engines: {node: '>=18'} hasBin: true @@ -17241,13 +17241,13 @@ packages: pkg-types@1.3.1: resolution: {integrity: sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==} - playwright-core@1.52.0: - resolution: {integrity: sha512-l2osTgLXSMeuLZOML9qYODUQoPPnUsKsb5/P6LJ2e6uPKXUdPK5WYhN4z03G+YNbWmGDY4YENauNu4ZKczreHg==} + playwright-core@1.55.1: + resolution: {integrity: sha512-Z6Mh9mkwX+zxSlHqdr5AOcJnfp+xUWLCt9uKV18fhzA8eyxUd8NUWzAjxUh55RZKSYwDGX0cfaySdhZJGMoJ+w==} engines: {node: '>=18'} hasBin: true - playwright@1.52.0: - resolution: {integrity: sha512-JAwMNMBlxJ2oD1kce4KPtMkDeKGHQstdpFPcPH3maElAXon/QZeTvtsfXmTMRyO9TslfoYOXkSsvao2nE1ilTw==} + playwright@1.55.1: + resolution: {integrity: sha512-cJW4Xd/G3v5ovXtJJ52MAOclqeac9S/aGGgRzLabuF8TnIb6xHvMzKIa6JmrRzUkeXJgfL1MhukP0NK6l39h3A==} engines: {node: '>=18'} hasBin: true @@ -24169,7 +24169,10 @@ snapshots: jest-runner: 25.5.4 jest-runtime: 25.5.4 transitivePeerDependencies: + - bufferutil + - canvas - supports-color + - utf-8-validate '@jest/test-sequencer@29.7.0': dependencies: @@ -24689,9 +24692,9 @@ snapshots: '@pkgjs/parseargs@0.11.0': optional: true - '@playwright/test@1.52.0': + '@playwright/test@1.55.1': dependencies: - playwright: 1.52.0 + playwright: 1.55.1 '@pmmmwh/react-refresh-webpack-plugin@0.5.17(@types/webpack@5.28.5(webpack-cli@4.10.0))(react-refresh@0.11.0)(type-fest@4.41.0)(webpack-dev-server@5.2.2)(webpack-hot-middleware@2.26.1)(webpack@5.101.0)': dependencies: @@ -42818,11 +42821,11 @@ snapshots: mlly: 1.7.4 pathe: 2.0.3 - playwright-core@1.52.0: {} + playwright-core@1.55.1: {} - playwright@1.52.0: + playwright@1.55.1: dependencies: - playwright-core: 1.52.0 + playwright-core: 1.55.1 optionalDependencies: fsevents: 2.3.2 diff --git a/workspaces/ballerina/ballerina-core/src/interfaces/data-mapper.ts b/workspaces/ballerina/ballerina-core/src/interfaces/data-mapper.ts index a0f6be413f5..bc6569f90a7 100644 --- a/workspaces/ballerina/ballerina-core/src/interfaces/data-mapper.ts +++ b/workspaces/ballerina/ballerina-core/src/interfaces/data-mapper.ts @@ -24,7 +24,14 @@ export enum TypeKind { Record = "record", Array = "array", String = "string", + StringChar = "string:Char", Int = "int", + IntSigned8 = "int:Signed8", + IntSigned16 = "int:Signed16", + IntSigned32 = "int:Signed32", + IntUnsigned8 = "int:Unsigned8", + IntUnsigned16 = "int:Unsigned16", + IntUnsigned32 = "int:Unsigned32", Float = "float", Decimal = "decimal", Boolean = "boolean", @@ -115,6 +122,7 @@ export interface ExpandedDMModel { rootViewId: string; query?: Query; mapping_fields?: Record; + triggerRefresh?: boolean; } export interface DMModel { @@ -127,6 +135,7 @@ export interface DMModel { query?: Query; focusInputs?: Record; mapping_fields?: Record; + triggerRefresh?: boolean; } export interface ModelState { diff --git a/workspaces/ballerina/ballerina-core/src/interfaces/extended-lang-client.ts b/workspaces/ballerina/ballerina-core/src/interfaces/extended-lang-client.ts index 87b6d04102c..38500687843 100644 --- a/workspaces/ballerina/ballerina-core/src/interfaces/extended-lang-client.ts +++ b/workspaces/ballerina/ballerina-core/src/interfaces/extended-lang-client.ts @@ -470,6 +470,10 @@ export interface MapWithFnRequest { subMappingName?: string; } +export interface ClearTypeCacheResponse { + success: boolean; +} + export interface GetDataMapperCodedataRequest { filePath: string; codedata: CodeData; diff --git a/workspaces/ballerina/ballerina-core/src/rpc-types/data-mapper/index.ts b/workspaces/ballerina/ballerina-core/src/rpc-types/data-mapper/index.ts index dce3f653c96..0508511647d 100644 --- a/workspaces/ballerina/ballerina-core/src/rpc-types/data-mapper/index.ts +++ b/workspaces/ballerina/ballerina-core/src/rpc-types/data-mapper/index.ts @@ -41,7 +41,8 @@ import { DMModelRequest, ProcessTypeReferenceResponse, ProcessTypeReferenceRequest, - ExpandedDMModelResponse + ExpandedDMModelResponse, + ClearTypeCacheResponse } from "../../interfaces/extended-lang-client"; export interface DataMapperAPI { @@ -64,4 +65,5 @@ export interface DataMapperAPI { getProperty: (params: PropertyRequest) => Promise; getExpandedDMFromDMModel: (params: DMModelRequest) => Promise; getProcessTypeReference: (params: ProcessTypeReferenceRequest) => Promise; + clearTypeCache: () => Promise; } diff --git a/workspaces/ballerina/ballerina-core/src/rpc-types/data-mapper/rpc-type.ts b/workspaces/ballerina/ballerina-core/src/rpc-types/data-mapper/rpc-type.ts index 774ebd4faa7..875a6920739 100644 --- a/workspaces/ballerina/ballerina-core/src/rpc-types/data-mapper/rpc-type.ts +++ b/workspaces/ballerina/ballerina-core/src/rpc-types/data-mapper/rpc-type.ts @@ -43,7 +43,8 @@ import { DMModelRequest, ProcessTypeReferenceResponse, ProcessTypeReferenceRequest, - ExpandedDMModelResponse + ExpandedDMModelResponse, + ClearTypeCacheResponse } from "../../interfaces/extended-lang-client"; import { RequestType } from "vscode-messenger-common"; @@ -67,3 +68,4 @@ export const getAllDataMapperSource: RequestType = { method: `${_preFix}/getProperty` }; export const getExpandedDMFromDMModel: RequestType = { method: `${_preFix}/getExpandedDMFromDMModel` }; export const getProcessTypeReference: RequestType = { method: `${_preFix}/getProcessTypeReference` }; +export const clearTypeCache: RequestType = { method: `${_preFix}/clearTypeCache` }; diff --git a/workspaces/ballerina/ballerina-extension/package.json b/workspaces/ballerina/ballerina-extension/package.json index ad858fcdcd1..15c4e053aed 100644 --- a/workspaces/ballerina/ballerina-extension/package.json +++ b/workspaces/ballerina/ballerina-extension/package.json @@ -2,7 +2,7 @@ "name": "ballerina", "displayName": "Ballerina", "description": "Ballerina Language support, debugging, graphical visualization, AI-based data-mapping and many more.", - "version": "5.4.1", + "version": "5.4.2", "publisher": "wso2", "icon": "resources/images/ballerina.png", "homepage": "https://wso2.com/ballerina/vscode/docs", diff --git a/workspaces/ballerina/ballerina-extension/src/core/extended-language-client.ts b/workspaces/ballerina/ballerina-extension/src/core/extended-language-client.ts index 0a95898359d..1094af3ecbd 100644 --- a/workspaces/ballerina/ballerina-extension/src/core/extended-language-client.ts +++ b/workspaces/ballerina/ballerina-extension/src/core/extended-language-client.ts @@ -259,7 +259,8 @@ import { onMigrationToolLogs, GetMigrationToolsResponse, DeleteSubMappingRequest, - DeleteClauseRequest + DeleteClauseRequest, + ClearTypeCacheResponse } from "@wso2/ballerina-core"; import { BallerinaExtension } from "./index"; import { debug, handlePullModuleProgress } from "../utils"; @@ -357,6 +358,7 @@ enum EXTENDED_APIS { DATA_MAPPER_CODEDATA = 'dataMapper/nodePosition', DATA_MAPPER_SUB_MAPPING_CODEDATA = 'dataMapper/subMapping', DATA_MAPPER_PROPERTY = 'dataMapper/fieldPosition', + DATA_MAPPER_CLEAR_TYPE_CACHE = 'dataMapper/clearTypeCache', VIEW_CONFIG_VARIABLES = 'configEditor/getConfigVariables', UPDATE_CONFIG_VARIABLES = 'configEditor/updateConfigVariables', VIEW_CONFIG_VARIABLES_V2 = 'configEditorV2/getConfigVariables', @@ -807,6 +809,10 @@ export class ExtendedLangClient extends LanguageClient implements ExtendedLangCl return this.sendRequest(EXTENDED_APIS.DATA_MAPPER_PROPERTY, params); } + async clearTypeCache(): Promise { + return this.sendRequest(EXTENDED_APIS.DATA_MAPPER_CLEAR_TYPE_CACHE); + } + async getGraphqlModel(params: GraphqlDesignServiceParams): Promise { return this.sendRequest(EXTENDED_APIS.GRAPHQL_DESIGN_MODEL, params); } diff --git a/workspaces/ballerina/ballerina-extension/src/rpc-managers/data-mapper/rpc-handler.ts b/workspaces/ballerina/ballerina-extension/src/rpc-managers/data-mapper/rpc-handler.ts index 31773447c65..98e04b388c2 100644 --- a/workspaces/ballerina/ballerina-extension/src/rpc-managers/data-mapper/rpc-handler.ts +++ b/workspaces/ballerina/ballerina-extension/src/rpc-managers/data-mapper/rpc-handler.ts @@ -25,6 +25,7 @@ import { addSubMapping, AddSubMappingRequest, AllDataMapperSourceRequest, + clearTypeCache, convertToQuery, ConvertToQueryRequest, DataMapperModelRequest, @@ -80,4 +81,5 @@ export function registerDataMapperRpcHandlers(messenger: Messenger) { messenger.onRequest(getProperty, (args: PropertyRequest) => rpcManger.getProperty(args)); messenger.onRequest(getExpandedDMFromDMModel, (args: DMModelRequest) => rpcManger.getExpandedDMFromDMModel(args)); messenger.onRequest(getProcessTypeReference, (args: ProcessTypeReferenceRequest) => rpcManger.getProcessTypeReference(args)); + messenger.onRequest(clearTypeCache, () => rpcManger.clearTypeCache()); } diff --git a/workspaces/ballerina/ballerina-extension/src/rpc-managers/data-mapper/rpc-manager.ts b/workspaces/ballerina/ballerina-extension/src/rpc-managers/data-mapper/rpc-manager.ts index 8f6869cc5ec..a374db3a2b0 100644 --- a/workspaces/ballerina/ballerina-extension/src/rpc-managers/data-mapper/rpc-manager.ts +++ b/workspaces/ballerina/ballerina-extension/src/rpc-managers/data-mapper/rpc-manager.ts @@ -22,6 +22,7 @@ import { AddClausesRequest, AddSubMappingRequest, AllDataMapperSourceRequest, + ClearTypeCacheResponse, ConvertToQueryRequest, DataMapperAPI, DataMapperModelRequest, @@ -409,4 +410,15 @@ export class DataMapperRpcManager implements DataMapperAPI { }); }); } + + async clearTypeCache(): Promise { + return new Promise(async (resolve) => { + await StateMachine + .langClient() + .clearTypeCache() + .then((resp) => { + resolve(resp); + }); + }); + } } diff --git a/workspaces/ballerina/ballerina-extension/src/rpc-managers/data-mapper/utils.ts b/workspaces/ballerina/ballerina-extension/src/rpc-managers/data-mapper/utils.ts index c45223f6b68..471fc7261d5 100644 --- a/workspaces/ballerina/ballerina-extension/src/rpc-managers/data-mapper/utils.ts +++ b/workspaces/ballerina/ballerina-extension/src/rpc-managers/data-mapper/utils.ts @@ -517,7 +517,8 @@ export function expandDMModel( mappings: model.mappings, query: model.query, source: "", - rootViewId + rootViewId, + triggerRefresh: model.triggerRefresh }; } diff --git a/workspaces/ballerina/ballerina-extension/src/views/visualizer/webview.ts b/workspaces/ballerina/ballerina-extension/src/views/visualizer/webview.ts index e64ae2a9c7d..4cb902a33f8 100644 --- a/workspaces/ballerina/ballerina-extension/src/views/visualizer/webview.ts +++ b/workspaces/ballerina/ballerina-extension/src/views/visualizer/webview.ts @@ -68,7 +68,7 @@ export class VisualizerWebview { const documentUri = document.document.uri.toString(); const isDocumentUnderProject = documentUri.includes(projectUri); // Reset visualizer the undo-redo stack if user did changes in the editor - if (isOpened && isDocumentUnderProject) { + if (isOpened && isDocumentUnderProject && !this._panel?.active) { undoRedoManager.reset(); } diff --git a/workspaces/ballerina/ballerina-rpc-client/src/rpc-clients/data-mapper/rpc-client.ts b/workspaces/ballerina/ballerina-rpc-client/src/rpc-clients/data-mapper/rpc-client.ts index d0c9fcf2233..20a4f0978b3 100644 --- a/workspaces/ballerina/ballerina-rpc-client/src/rpc-clients/data-mapper/rpc-client.ts +++ b/workspaces/ballerina/ballerina-rpc-client/src/rpc-clients/data-mapper/rpc-client.ts @@ -22,6 +22,7 @@ import { AddClausesRequest, AddSubMappingRequest, AllDataMapperSourceRequest, + ClearTypeCacheResponse, ConvertToQueryRequest, DMModelRequest, DataMapperAPI, @@ -48,6 +49,7 @@ import { addClauses, addNewArrayElement, addSubMapping, + clearTypeCache, convertToQuery, deleteClause, deleteMapping, @@ -150,4 +152,8 @@ export class DataMapperRpcClient implements DataMapperAPI { getProcessTypeReference(params: ProcessTypeReferenceRequest): Promise { return this._messenger.sendRequest(getProcessTypeReference, HOST_EXTENSION, params); } + + clearTypeCache(): Promise { + return this._messenger.sendRequest(clearTypeCache, HOST_EXTENSION); + } } diff --git a/workspaces/ballerina/ballerina-visualizer/src/Hooks.tsx b/workspaces/ballerina/ballerina-visualizer/src/Hooks.tsx index 49933195e92..e05b886b71d 100644 --- a/workspaces/ballerina/ballerina-visualizer/src/Hooks.tsx +++ b/workspaces/ballerina/ballerina-visualizer/src/Hooks.tsx @@ -18,6 +18,7 @@ import { useQuery } from '@tanstack/react-query'; import { useRpcContext } from '@wso2/ballerina-rpc-client'; import { DMViewState, LinePosition } from '@wso2/ballerina-core'; +import { useRef } from 'react'; export const useDataMapperModel = ( filePath: string, @@ -28,6 +29,8 @@ export const useDataMapperModel = ( const viewId = viewState?.viewId; const codedata = viewState?.codedata; + const triggerRefresh = useRef(false); + const getDMModel = async () => { try { const modelParams = { @@ -43,6 +46,11 @@ export const useDataMapperModel = ( .getDataMapperRpcClient() .getDataMapperModel(modelParams); + if (triggerRefresh.current) { + res.mappingsModel.triggerRefresh = true; + triggerRefresh.current = false; + } + console.log('>>> [Data Mapper] Model:', res); return res.mappingsModel; } catch (error) { @@ -57,10 +65,15 @@ export const useDataMapperModel = ( isError, refetch } = useQuery({ - queryKey: ['getDMModel', { codedata, viewId }], - queryFn: () => getDMModel(), + queryKey: ['getDMModel', codedata, viewId], + queryFn: getDMModel, networkMode: 'always' }); - return {model, isFetching, isError, refetch}; + const refreshDMModel = async () => { + triggerRefresh.current = true; + await refetch(); + }; + + return { model, isFetching, isError, refreshDMModel }; }; diff --git a/workspaces/ballerina/ballerina-visualizer/src/views/BI/Connection/ConnectorView/index.tsx b/workspaces/ballerina/ballerina-visualizer/src/views/BI/Connection/ConnectorView/index.tsx index 6d9a66f70ff..bffcf553923 100644 --- a/workspaces/ballerina/ballerina-visualizer/src/views/BI/Connection/ConnectorView/index.tsx +++ b/workspaces/ballerina/ballerina-visualizer/src/views/BI/Connection/ConnectorView/index.tsx @@ -119,7 +119,7 @@ export function ConnectorView(props: ConnectorViewProps) { const [isSearching, setIsSearching] = useState(false); const [fetchingInfo, setFetchingInfo] = useState(false); const [selectedConnectorCategory, setSelectedConnectorCategory] = useState( - openCustomConnectorView? "LocalConnectors" : "StandardLibrary" + openCustomConnectorView ? "LocalConnectors" : "StandardLibrary" ); useEffect(() => { @@ -152,9 +152,8 @@ export function ConnectorView(props: ConnectorViewProps) { }) .then(async (model) => { console.log(">>> bi connectors", model); - const filtered = await filterCategories(model.categories); - console.log(">>> bi filtered connectors", filtered); - setConnectors(filtered); + console.log(">>> bi filtered connectors", model.categories); + setConnectors(model.categories); }) .finally(() => { setIsSearching(false); @@ -188,9 +187,8 @@ export function ConnectorView(props: ConnectorViewProps) { }) .then(async (model) => { console.log(">>> bi searched connectors", model); - const filtered = await filterCategories(model.categories); - console.log(">>> bi filtered connectors", filtered); - setConnectors(filtered); + console.log(">>> bi filtered connectors", model.categories); + setConnectors(model.categories); }) .finally(() => { setIsSearching(false); diff --git a/workspaces/ballerina/ballerina-visualizer/src/views/DataMapper/DataMapperView.tsx b/workspaces/ballerina/ballerina-visualizer/src/views/DataMapper/DataMapperView.tsx index 7909fd0644f..4f84d88edcf 100644 --- a/workspaces/ballerina/ballerina-visualizer/src/views/DataMapper/DataMapperView.tsx +++ b/workspaces/ballerina/ballerina-visualizer/src/views/DataMapper/DataMapperView.tsx @@ -92,7 +92,8 @@ export function DataMapperView(props: DataMapperProps) { const { model, isFetching, - isError + isError, + refreshDMModel } = useDataMapperModel(filePath, viewState, position); const prevPositionRef = useRef(position); @@ -119,10 +120,12 @@ export function DataMapperView(props: DataMapperProps) { const currentSignature = JSON.stringify(getModelSignature(model)); const prevSignature = prevSignatureRef.current; - const hasInputsChanged = hasSignatureChanged(currentSignature, prevSignature, 'inputs'); - const hasOutputChanged = hasSignatureChanged(currentSignature, prevSignature, 'output'); - const hasSubMappingsChanged = hasSignatureChanged(currentSignature, prevSignature, 'subMappings'); - const hasRefsChanged = hasSignatureChanged(currentSignature, prevSignature, 'refs'); + const triggerRefresh = model.triggerRefresh; + + const hasInputsChanged = triggerRefresh || hasSignatureChanged(currentSignature, prevSignature, 'inputs'); + const hasOutputChanged = triggerRefresh || hasSignatureChanged(currentSignature, prevSignature, 'output'); + const hasSubMappingsChanged = triggerRefresh || hasSignatureChanged(currentSignature, prevSignature, 'subMappings'); + const hasRefsChanged = triggerRefresh || hasSignatureChanged(currentSignature, prevSignature, 'refs'); // Check if it's already an ExpandedDMModel const isExpandedModel = !('refs' in model); @@ -189,21 +192,6 @@ export function DataMapperView(props: DataMapperProps) { [modelState] ); - - const onDMClose = () => { - onClose ? onClose() : rpcClient.getVisualizerRpcClient()?.goBack(); - } - - const onEdit = () => { - const context: VisualizerLocation = { - view: MACHINE_VIEW.BIDataMapperForm, - identifier: modelState.model.output.name, - documentUri: filePath, - }; - - rpcClient.getVisualizerRpcClient().openView({ type: EVENT_TYPE.OPEN_VIEW, location: context }); - } - const updateExpression = async (outputId: string, expression: string, viewId: string, name: string) => { try { const resp = await rpcClient @@ -537,6 +525,42 @@ export function DataMapperView(props: DataMapperProps) { parentField.isDeepNested = false; } + + + const onDMClose = () => { + onClose ? onClose() : rpcClient.getVisualizerRpcClient()?.goBack(); + } + + const onDMRefresh = async () => { + try { + const resp = await rpcClient + .getDataMapperRpcClient() + .clearTypeCache(); + console.log(">>> [Data Mapper] clearTypeCache response:", resp); + } catch (error) { + console.error(error); + } + await refreshDMModel(); + }; + + const onDMReset = async () => { + await deleteMapping( + { output: name, expression: undefined }, + name + ); + }; + + const onEdit = () => { + const context: VisualizerLocation = { + view: MACHINE_VIEW.BIDataMapperForm, + identifier: modelState.model.output.name, + documentUri: filePath, + }; + + rpcClient.getVisualizerRpcClient().openView({ type: EVENT_TYPE.OPEN_VIEW, location: context }); + } + + useEffect(() => { // Hack to hit the error boundary if (isError) { @@ -581,7 +605,7 @@ export function DataMapperView(props: DataMapperProps) { lineOffset: lineOffset, offset: charOffset, codedata: viewState.codedata, - property: property, + property: { ...property, valueType: "DATA_MAPPING_EXPRESSION" } }, completionContext: { triggerKind: triggerCharacter ? 2 : 1, @@ -652,6 +676,8 @@ export function DataMapperView(props: DataMapperProps) { modelState={modelState} name={name} onClose={onDMClose} + onRefresh={onDMRefresh} + onReset={onDMReset} onEdit={reusable ? onEdit : undefined} applyModifications={updateExpression} addArrayElement={addArrayElement} diff --git a/workspaces/ballerina/data-mapper/src/components/DataMapper/DataMapperEditor.tsx b/workspaces/ballerina/data-mapper/src/components/DataMapper/DataMapperEditor.tsx index 3ad59f53d24..8ae68b725f9 100644 --- a/workspaces/ballerina/data-mapper/src/components/DataMapper/DataMapperEditor.tsx +++ b/workspaces/ballerina/data-mapper/src/components/DataMapper/DataMapperEditor.tsx @@ -126,6 +126,8 @@ export function DataMapperEditor(props: DataMapperEditorProps) { name, applyModifications, onClose, + onRefresh, + onReset, onEdit, addArrayElement, handleView, @@ -280,6 +282,7 @@ export function DataMapperEditor(props: DataMapperEditorProps) { useDMCollapsedFieldsStore.getState().resetFields(); useDMExpandedFieldsStore.getState().resetFields(); useDMExpressionBarStore.getState().resetExpressionBarStore(); + useDMQueryClausesPanelStore.getState().resetQueryClausesPanelStore(); } const handleOnClose = () => { @@ -330,6 +333,8 @@ export function DataMapperEditor(props: DataMapperEditorProps) { hasEditDisabled={!!errorKind} onClose={handleOnClose} onBack={handleOnBack} + onRefresh={onRefresh} + onReset={onReset} onEdit={onEdit} autoMapWithAI={autoMapWithAI} undoRedoGroup={undoRedoGroup} diff --git a/workspaces/ballerina/data-mapper/src/components/DataMapper/Header/DataMapperHeader.tsx b/workspaces/ballerina/data-mapper/src/components/DataMapper/Header/DataMapperHeader.tsx index 624931a2c90..d9e4b30a9f2 100644 --- a/workspaces/ballerina/data-mapper/src/components/DataMapper/Header/DataMapperHeader.tsx +++ b/workspaces/ballerina/data-mapper/src/components/DataMapper/Header/DataMapperHeader.tsx @@ -18,7 +18,7 @@ // tslint:disable: jsx-no-multiline-js import React from "react"; import styled from "@emotion/styled"; -import { Codicon, Icon } from "@wso2/ui-toolkit"; +import { Button, Codicon, Icon, ProgressRing } from "@wso2/ui-toolkit"; import HeaderSearchBox from "./HeaderSearchBox"; import HeaderBreadcrumb from "./HeaderBreadcrumb"; @@ -27,6 +27,7 @@ import { VSCodeButton } from "@vscode/webview-ui-toolkit/react"; import AutoMapButton from "./AutoMapButton"; import ExpressionBarWrapper from "./ExpressionBar"; import EditButton from "./EditButton"; +import { RefreshResetGroup } from "./RefreshResetGroup"; export interface DataMapperHeaderProps { views: View[]; @@ -35,12 +36,14 @@ export interface DataMapperHeaderProps { onClose: () => void; onBack: () => void; onEdit?: () => void; + onRefresh: () => Promise; + onReset: () => Promise; autoMapWithAI: () => Promise; undoRedoGroup: () => JSX.Element; } export function DataMapperHeader(props: DataMapperHeaderProps) { - const { views, switchView, hasEditDisabled, onClose, onBack, onEdit, autoMapWithAI, undoRedoGroup } = props; + const { views, switchView, hasEditDisabled, onClose, onBack, onRefresh, onReset, onEdit, autoMapWithAI, undoRedoGroup } = props; const handleAutoMap = async () => { await autoMapWithAI(); @@ -53,6 +56,8 @@ export function DataMapperHeader(props: DataMapperHeaderProps) { {undoRedoGroup && undoRedoGroup()} + + Data Mapper {!hasEditDisabled && ( @@ -94,7 +99,7 @@ const HeaderContent = styled.div` background-color: var(--vscode-editorWidget-background); justify-content: space-between; align-items: center; - gap: 12px; + gap: 4px; border-bottom: 1px solid rgba(102,103,133,0.15); `; @@ -105,11 +110,17 @@ const Title = styled.h2` color: var(--vscode-foreground); `; +const VerticalDivider = styled.div` + height: 20px; + width: 1px; + background-color: var(--dropdown-border); +`; + const RightContainer = styled.div<{ isClickable: boolean }>` display: flex; align-items: center; gap: 12px; - pointer-events: ${({ isClickable }) => (isClickable ? 'auto' : 'none')}; + pointer-events: ${({ isClickable }) => (isClickable ? "auto" : "none")}; opacity: ${({ isClickable }) => (isClickable ? 1 : 0.5)}; `; diff --git a/workspaces/ballerina/data-mapper/src/components/DataMapper/Header/RefreshResetGroup.tsx b/workspaces/ballerina/data-mapper/src/components/DataMapper/Header/RefreshResetGroup.tsx new file mode 100644 index 00000000000..21df6374939 --- /dev/null +++ b/workspaces/ballerina/data-mapper/src/components/DataMapper/Header/RefreshResetGroup.tsx @@ -0,0 +1,76 @@ +/** + * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com) All Rights Reserved. + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import React, { useState } from "react"; +import styled from "@emotion/styled"; +import { Button, Codicon, ProgressRing } from "@wso2/ui-toolkit"; + +const ButtonGroup = styled.div` + display: flex; + align-items: center; +`; + +interface ActionButtonProps { + onClick: () => Promise; + iconName: string; + tooltip: string; +} + +function ActionButton({ onClick, iconName, tooltip }: ActionButtonProps) { + const [inProgress, setInProgress] = useState(false); + + const handleOnClick = async () => { + setInProgress(true); + await onClick(); + setInProgress(false); + }; + + return ( + + ); +} + +interface RefreshResetGroupProps { + onRefresh: () => Promise; + onReset: () => Promise; +} + +export function RefreshResetGroup({ onRefresh, onReset }: RefreshResetGroupProps) { + return ( + + + + + ); +} diff --git a/workspaces/ballerina/data-mapper/src/components/Diagram/Label/MappingOptionsWidget.tsx b/workspaces/ballerina/data-mapper/src/components/Diagram/Label/MappingOptionsWidget.tsx index f2e0467e5f0..b194112a2d2 100644 --- a/workspaces/ballerina/data-mapper/src/components/Diagram/Label/MappingOptionsWidget.tsx +++ b/workspaces/ballerina/data-mapper/src/components/Diagram/Label/MappingOptionsWidget.tsx @@ -159,11 +159,6 @@ export function MappingOptionsWidget(props: MappingOptionsWidgetProps) { id: "a2s-direct", label: getItemElement("a2s-direct", "Extract Single Element from Array"), onClick: wrapWithProgress(onClickMapArraysAccessSingleton) - }, - { - id: "a2s-aggregate", - label: getItemElement("a2s-aggregate", "Aggregate using Query"), - onClick: wrapWithProgress(onClickAggregateArray) } ]; @@ -178,7 +173,7 @@ export function MappingOptionsWidget(props: MappingOptionsWidgetProps) { const defaultMenuItems: Item[] = [ { id: "a2a-direct", - label: getItemElement("direct", "Map directly"), + label: getItemElement("direct", "Map Anyway"), onClick: wrapWithProgress(onClickMapDirectly) } ]; diff --git a/workspaces/ballerina/data-mapper/src/components/Diagram/Node/commons/DataMapperNode.ts b/workspaces/ballerina/data-mapper/src/components/Diagram/Node/commons/DataMapperNode.ts index d409fef383e..4912f5006b3 100644 --- a/workspaces/ballerina/data-mapper/src/components/Diagram/Node/commons/DataMapperNode.ts +++ b/workspaces/ballerina/data-mapper/src/components/Diagram/Node/commons/DataMapperNode.ts @@ -93,7 +93,7 @@ export abstract class DataMapperNodeModel extends NodeModel | void; abstract initLinks(): void; protected async addPortsForInputField(attributes: InputPortAttributes): Promise { diff --git a/workspaces/ballerina/data-mapper/src/components/Diagram/hooks/useDiagramModel.ts b/workspaces/ballerina/data-mapper/src/components/Diagram/hooks/useDiagramModel.ts index 751a9ce04b5..85babd4ccc0 100644 --- a/workspaces/ballerina/data-mapper/src/components/Diagram/hooks/useDiagramModel.ts +++ b/workspaces/ballerina/data-mapper/src/components/Diagram/hooks/useDiagramModel.ts @@ -26,12 +26,13 @@ import { useDMSearchStore } from "../../../store/store"; import { InputNode } from "../Node"; import { getErrorKind } from "../utils/common-utils"; import { OverlayLayerModel } from "../OverlayLayer/OverlayLayerModel"; +import { useEffect } from "react"; export const useDiagramModel = ( nodes: DataMapperNodeModel[], diagramModel: DiagramModel, onError:(kind: ErrorNodeKind) => void, - zoomLevel: number, + zoomLevel: number ): { updatedModel: DiagramModel; isFetching: boolean; @@ -86,7 +87,7 @@ export const useDiagramModel = ( data: updatedModel, isFetching, isError, - refetch, + refetch } = useQuery({ queryKey: [ 'diagramModel', @@ -103,5 +104,11 @@ export const useDiagramModel = ( networkMode: 'always', }); + useEffect(() => { + if (model?.triggerRefresh) { + refetch(); + } + }, [model, refetch]); + return { updatedModel, isFetching, isError, refetch }; }; diff --git a/workspaces/ballerina/data-mapper/src/components/Diagram/utils/type-utils.ts b/workspaces/ballerina/data-mapper/src/components/Diagram/utils/type-utils.ts index e1bc4b46be6..93706781864 100644 --- a/workspaces/ballerina/data-mapper/src/components/Diagram/utils/type-utils.ts +++ b/workspaces/ballerina/data-mapper/src/components/Diagram/utils/type-utils.ts @@ -61,6 +61,32 @@ export function isEnumMember(parent: InputNode): boolean { } export function isPrimitive(typeKind: TypeKind): boolean { - return typeKind === TypeKind.String || typeKind === TypeKind.Int || typeKind === TypeKind.Float || - typeKind === TypeKind.Decimal || typeKind === TypeKind.Boolean || typeKind === TypeKind.Byte; + const genericTypeKind = getGenericTypeKind(typeKind); + return genericTypeKind === TypeKind.String || + genericTypeKind === TypeKind.Int || + genericTypeKind === TypeKind.Float || + genericTypeKind === TypeKind.Decimal || + genericTypeKind === TypeKind.Boolean || + genericTypeKind === TypeKind.Byte; } + +export function getGenericTypeKind(typeKind: TypeKind): TypeKind { + switch (typeKind) { + case TypeKind.IntSigned8: + return TypeKind.Int; + case TypeKind.IntSigned16: + return TypeKind.Int; + case TypeKind.IntSigned32: + return TypeKind.Int; + case TypeKind.IntUnsigned8: + return TypeKind.Int; + case TypeKind.IntUnsigned16: + return TypeKind.Int; + case TypeKind.IntUnsigned32: + return TypeKind.Int; + case TypeKind.StringChar: + return TypeKind.String; + default: + return typeKind; + } +}; diff --git a/workspaces/ballerina/data-mapper/src/index.tsx b/workspaces/ballerina/data-mapper/src/index.tsx index d1140ed4dc5..e46a4914ea2 100644 --- a/workspaces/ballerina/data-mapper/src/index.tsx +++ b/workspaces/ballerina/data-mapper/src/index.tsx @@ -64,7 +64,6 @@ export interface DataMapperEditorProps { name: string; applyModifications: (outputId: string, expression: string, viewId: string, name: string) => Promise; addArrayElement: (outputId: string, viewId: string, name: string) => Promise; - generateForm: (formProps: DMFormProps) => JSX.Element; convertToQuery: (mapping: Mapping, clauseType: ResultClauseType, viewId: string, name: string) => Promise; addClauses: (clause: IntermediateClause, targetField: string, isNew: boolean, index:number) => Promise; deleteClause: (targetField: string, index: number) => Promise; @@ -75,9 +74,12 @@ export interface DataMapperEditorProps { mapWithTransformFn: (mapping: Mapping, metadata: FnMetadata, viewId: string) => Promise; goToFunction: (functionRange: LineRange) => Promise; enrichChildFields: (parentField: IOType) => Promise; + onRefresh: () => Promise; + onReset: () => Promise; onClose: () => void; onEdit?: () => void; handleView: (viewId: string, isSubMapping?: boolean) => void; + generateForm: (formProps: DMFormProps) => JSX.Element; undoRedoGroup: () => JSX.Element; } diff --git a/workspaces/ballerina/data-mapper/src/store/store.ts b/workspaces/ballerina/data-mapper/src/store/store.ts index e5b2fa3248a..545d518bb8c 100644 --- a/workspaces/ballerina/data-mapper/src/store/store.ts +++ b/workspaces/ballerina/data-mapper/src/store/store.ts @@ -162,9 +162,13 @@ export const useDMExpressionBarStore = create((set export interface DataMapperQueryClausesPanelState { isQueryClausesPanelOpen: boolean; setIsQueryClausesPanelOpen: (isQueryClausesPanelOpen: boolean) => void; + resetQueryClausesPanelStore: () => void; } export const useDMQueryClausesPanelStore = create((set) => ({ isQueryClausesPanelOpen: false, setIsQueryClausesPanelOpen: (isQueryClausesPanelOpen: boolean) => set({ isQueryClausesPanelOpen }), + resetQueryClausesPanelStore: () => set({ + isQueryClausesPanelOpen: false + }) })); diff --git a/workspaces/bi/bi-extension/CHANGELOG.md b/workspaces/bi/bi-extension/CHANGELOG.md index 0101b4c2ea7..9a34550e2af 100644 --- a/workspaces/bi/bi-extension/CHANGELOG.md +++ b/workspaces/bi/bi-extension/CHANGELOG.md @@ -7,6 +7,20 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) ## [Unreleased] +## [1.3.2](https://github.com/wso2/vscode-extensions/compare/ballerina-integrator-1.3.1...ballerina-integrator-1.3.2) - 2025-10-26 + +### Changed + +- **Data Mapper** Enable reset and refresh options. + +### Fixed + +- **Editor** Allow artifact creation even when corresponding source files are missing. +- **Data Mapper** — Add support for mappings with built-in Ballerina sub-types (e.g., int:Signed32), fix creation using types from sub-modules, enable expression-bar completions for reusable mappers, and correct link rendering for optional field access. +- **Type Browser** — Improve type filtering based on user queries. +- **Service Class Designer** — Enable connection generation for clients created from WSDL files. + + ## [1.3.1](https://github.com/wso2/vscode-extensions/compare/ballerina-integrator-1.3.0...ballerina-integrator-1.3.1) - 2025-10-15 ### Changed diff --git a/workspaces/bi/bi-extension/package.json b/workspaces/bi/bi-extension/package.json index c2572eeeabf..0aeb1056bd1 100644 --- a/workspaces/bi/bi-extension/package.json +++ b/workspaces/bi/bi-extension/package.json @@ -2,7 +2,7 @@ "name": "ballerina-integrator", "displayName": "WSO2 Integrator: BI", "description": "An extension which gives a development environment for designing, developing, debugging, and testing integration solutions.", - "version": "1.3.1", + "version": "1.3.2", "publisher": "wso2", "icon": "resources/images/wso2-ballerina-integrator-logo.png", "repository": { @@ -196,7 +196,7 @@ "webpack": "^5.99.8", "webpack-cli": "^6.0.1", "webpack-permissions-plugin": "^1.0.9", - "@playwright/test": "~1.52.0", + "@playwright/test": "~1.55.1", "@wso2/playwright-vscode-tester": "workspace:*" } } diff --git a/workspaces/bi/bi-extension/src/project-explorer/project-explorer-provider.ts b/workspaces/bi/bi-extension/src/project-explorer/project-explorer-provider.ts index 3d38d3f2460..354115c107f 100644 --- a/workspaces/bi/bi-extension/src/project-explorer/project-explorer-provider.ts +++ b/workspaces/bi/bi-extension/src/project-explorer/project-explorer-provider.ts @@ -315,7 +315,8 @@ function getEntriesBI(components: ProjectStructureResponse): ProjectExplorerEntr if (localConnectors.children.length > 0) { localConnectors.collapsibleState = vscode.TreeItemCollapsibleState.Expanded; } - entries.push(localConnectors); + // REMOVE THE CUSTOM CONNECTOR TREE ITEM FOR NOW + // entries.push(localConnectors); return entries; } diff --git a/workspaces/choreo/choreo-extension/package.json b/workspaces/choreo/choreo-extension/package.json index 7ebb0206ea2..1c9071dd0d8 100644 --- a/workspaces/choreo/choreo-extension/package.json +++ b/workspaces/choreo/choreo-extension/package.json @@ -188,7 +188,7 @@ "postbuild": "pnpm run package && pnpm run copyVSIX" }, "devDependencies": { - "@playwright/test": "1.52.0", + "@playwright/test": "1.55.1", "@types/byline": "^4.2.36", "@types/js-yaml": "^4.0.9", "@types/mocha": "~10.0.1", diff --git a/workspaces/common-libs/playwright-vscode-tester/package.json b/workspaces/common-libs/playwright-vscode-tester/package.json index 35ba6e602e4..22e30adc565 100644 --- a/workspaces/common-libs/playwright-vscode-tester/package.json +++ b/workspaces/common-libs/playwright-vscode-tester/package.json @@ -31,8 +31,8 @@ "hpagent": "~1.2.0", "targz": "~1.0.1", "unzipper": "~0.12.3", - "playwright-core": "~1.52.0", + "playwright-core": "~1.55.1", "got": "14.4.7", - "@playwright/test": "1.52.0" + "@playwright/test": "1.55.1" } } diff --git a/workspaces/mi/mi-extension/package.json b/workspaces/mi/mi-extension/package.json index 346a9caf352..0f97d339e23 100644 --- a/workspaces/mi/mi-extension/package.json +++ b/workspaces/mi/mi-extension/package.json @@ -988,8 +988,8 @@ "ts-morph": "^26.0.0", "await-notify": "^1.0.1", "yaml": "~2.8.0", - "@playwright/test": "~1.52.0", - "playwright-core": "~1.52.0" + "@playwright/test": "~1.55.1", + "playwright-core": "~1.55.1" }, "dependencies": { "copyfiles": "^2.4.1", diff --git a/workspaces/mi/mi-visualizer/package.json b/workspaces/mi/mi-visualizer/package.json index 4a4abf34bfc..cb90299a305 100644 --- a/workspaces/mi/mi-visualizer/package.json +++ b/workspaces/mi/mi-visualizer/package.json @@ -60,7 +60,7 @@ "@wso2/mi-component-diagram": "workspace:*", "lodash": "~4.17.21", "cron-expression-validator": "~1.0.20", - "@playwright/test": "1.52.0", + "@playwright/test": "1.55.1", "react-pdf": "~9.2.1", "@monaco-editor/react": "^4.7.0" }, diff --git a/workspaces/wso2-platform/wso2-platform-extension/package.json b/workspaces/wso2-platform/wso2-platform-extension/package.json index 3a479682516..228a2790b6e 100644 --- a/workspaces/wso2-platform/wso2-platform-extension/package.json +++ b/workspaces/wso2-platform/wso2-platform-extension/package.json @@ -212,7 +212,7 @@ "postbuild": "pnpm run package && pnpm run copyVSIX" }, "devDependencies": { - "@playwright/test": "1.52.0", + "@playwright/test": "1.55.1", "@types/byline": "^4.2.36", "@types/js-yaml": "^4.0.9", "@types/mocha": "~10.0.1",