Skip to content
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

feat(Data Mapper): Merge with Designer Vs-code Extension #3461

Merged
merged 13 commits into from
Oct 26, 2023
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion apps/vs-code-data-mapper-react/project.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
"defaultConfiguration": "production",
"options": {
"compiler": "babel",
"outputPath": "dist/apps/vs-code-data-mapper/webview",
"outputPath": "dist/apps/vs-code-designer/vs-code-data-mapper",
"index": "apps/vs-code-data-mapper-react/src/index.html",
"baseHref": "/",
"main": "apps/vs-code-data-mapper-react/src/main.tsx",
Expand Down
4 changes: 4 additions & 0 deletions apps/vs-code-designer/src/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ In Visual Studio Code, you can use the Azure Logic Apps (Standard) extension to

> Sign up today for your free Azure account and receive 12 months of free popular services, $200 free credit and 25+ always free services 👉 [Start Free](https://azure.microsoft.com/free/open-source).

# Azure Logic Apps - Data Mapper extension for Visual Studio Code
Elaina-Lee marked this conversation as resolved.
Show resolved Hide resolved

In Visual Studio Code, you can graphically describe transformations by mapping relationships between data types in a source schema and a target schema. After you install the Azure Logic Apps - Data Mapper extension, you can create direct basic relationships and more complex transformations using functions, handling any translation between supported schema types in the backend. For more information, see [Create maps to transform data in Azure Logic Apps with Visual Studio Code (preview)](https://go.microsoft.com/fwlink/?linkid=2234193).

## Azure Logic Apps (Standard) moves to the Resources tab

🎉 Version 2.15.15 and later: The Azure Logic Apps extension now follows the design pattern that Azure extensions follow. Previously, in the Azure window, an Azure Logic Apps extension section showed your Azure subscriptions and associated "remote" logic apps hosted in Azure.
Expand Down
101 changes: 101 additions & 0 deletions apps/vs-code-designer/src/app/commands/dataMapper/DataMapperExt.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
import { ext } from '../../../extensionVariables';
import { localize } from '../../../localize';
import DataMapperPanel from './DataMapperPanel';
import { startBackendRuntime } from './FxWorkflowRuntime';
import { webviewType } from './extensionConfig';
import type { MapDefinitionData, MapDefinitionEntry } from '@microsoft/logic-apps-data-mapper';
import * as yaml from 'js-yaml';
import * as path from 'path';
import { Uri, ViewColumn, window, workspace } from 'vscode';

export default class DataMapperExt {
public static async openDataMapperPanel(dataMapName: string, mapDefinitionData?: MapDefinitionData) {
const workflowFolder = DataMapperExt.getWorkspaceFolderFsPath();

if (workflowFolder) {
await startBackendRuntime(workflowFolder);

DataMapperExt.createOrShow(dataMapName, mapDefinitionData);
}
}

public static createOrShow(dataMapName: string, mapDefinitionData?: MapDefinitionData) {
// If a panel has already been created, re-show it
if (ext.dataMapPanelManagers[dataMapName]) {
// NOTE: Shouldn't need to re-send runtime port if webview has already been loaded/set up

window.showInformationMessage(`A Data Mapper panel is already open for this data map (${dataMapName}).`);
ext.dataMapPanelManagers[dataMapName].panel.reveal(ViewColumn.Active);
return;
}

const panel = window.createWebviewPanel(
webviewType, // Key used to reference the panel
dataMapName, // Title displayed in the tab
ViewColumn.Active, // Editor column to show the new webview panel in
{
enableScripts: true,
// NOTE: Keeps webview content state even when placed in background (same as browsers)
// - not as performant as vscode's get/setState, but likely not a concern at all for MVP
retainContextWhenHidden: true,
}
);

ext.dataMapPanelManagers[dataMapName] = new DataMapperPanel(panel, dataMapName);
ext.dataMapPanelManagers[dataMapName].panel.iconPath = {
light: Uri.file(path.join(ext.context.extensionPath, 'assets', 'light', 'wand.png')),
dark: Uri.file(path.join(ext.context.extensionPath, 'assets', 'dark', 'wand.png')),
};
ext.dataMapPanelManagers[dataMapName].updateWebviewPanelTitle();
ext.dataMapPanelManagers[dataMapName].mapDefinitionData = mapDefinitionData;

// From here, VSIX will handle any other initial-load-time events once receive webviewLoaded msg
}

public static getWorkspaceFolderFsPath() {
if (workspace.workspaceFolders) {
return workspace.workspaceFolders[0].uri.fsPath;
} else {
ext.showError(localize('MissingWorkspace', 'No VS Code folder/workspace found...'));
return '';
}
}

/*
Note: This method is copied from the MapDefinition.Utils.ts file in the @microsoft/logic-apps-data-mapper package
if this method gets updated, both need to be updated to keep them in sync. This exists as a copy to avoid a
package import issue.
*/
public static loadMapDefinition = (mapDefinitionString: string | undefined): MapDefinitionEntry => {
if (mapDefinitionString) {
// Add extra escapes around custom string values, so that we don't lose which ones are which
const modifiedMapDefinitionString = mapDefinitionString.replaceAll('"', `\\"`);
const mapDefinition = yaml.load(modifiedMapDefinitionString) as MapDefinitionEntry;

// Now that we've parsed the yml, remove the extra escaped quotes to restore the values
DataMapperExt.fixMapDefinitionCustomValues(mapDefinition);

return mapDefinition;
} else {
return {};
}
};

static fixMapDefinitionCustomValues = (mapDefinition: MapDefinitionEntry) => {
for (const key in mapDefinition) {
const curElement = mapDefinition[key];
if (typeof curElement === 'object' && curElement !== null) {
if (Array.isArray(curElement)) {
// TODO: Handle arrays better, currently fine for XML, but this will need to be re-addressed
// when we get to the advanced JSON array functionality
curElement.forEach((arrayElement) => DataMapperExt.fixMapDefinitionCustomValues(arrayElement));
} else {
DataMapperExt.fixMapDefinitionCustomValues(curElement);
}
} else if (Object.prototype.hasOwnProperty.call(mapDefinition, key) && typeof curElement === 'string') {
// eslint-disable-next-line no-param-reassign
mapDefinition[key] = curElement.replaceAll('\\"', '"');
}
}
};
}
Loading