From 1139c0c09c36f702512bb061dea23179f57da2dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nidhi=20Tyagi=20=F0=9F=8C=9F=F0=9F=90=87=F0=9F=8C=B4?= =?UTF-8?q?=E2=9D=84=EF=B8=8F?= Date: Thu, 27 Jul 2023 15:34:09 +0530 Subject: [PATCH 1/9] Runtime preview and back to studio integration --- package.json | 17 +++ src/web/client/assets/backToStudio.svg | 3 + src/web/client/assets/powerPages.svg | 10 ++ src/web/client/common/constants.ts | 1 + src/web/client/extension.ts | 10 ++ .../webViews/powerPagesNavigationProvider.ts | 138 ++++++++++++++++++ 6 files changed, 179 insertions(+) create mode 100644 src/web/client/assets/backToStudio.svg create mode 100644 src/web/client/assets/powerPages.svg create mode 100644 src/web/client/webViews/powerPagesNavigationProvider.ts diff --git a/package.json b/package.json index bf3b5adea..c0896546d 100644 --- a/package.json +++ b/package.json @@ -153,6 +153,14 @@ } ], "commands": [ + { + "command": "powerPagesFileExplorer.previewPowerPages", + "title": "Preview Power Pages site" + }, + { + "command": "powerPagesFileExplorer.backToStudio", + "title": "Back to Studio" + }, { "command": "extension.createChatView", "title": "Create Chat View" @@ -837,6 +845,15 @@ "visibility": "visible", "when": "never" } + ], + "explorer": [ + { + "id": "powerPagesFileExplorer", + "name": "POWERPAGE", + "when": "isWeb && virtualWorkspace", + "icon": "src/web/client/assets/powerPages.svg", + "contextualTitle": "Power Pages" + } ] }, "walkthroughs": [ diff --git a/src/web/client/assets/backToStudio.svg b/src/web/client/assets/backToStudio.svg new file mode 100644 index 000000000..a7103f1b5 --- /dev/null +++ b/src/web/client/assets/backToStudio.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/web/client/assets/powerPages.svg b/src/web/client/assets/powerPages.svg new file mode 100644 index 000000000..a249689f3 --- /dev/null +++ b/src/web/client/assets/powerPages.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/src/web/client/common/constants.ts b/src/web/client/common/constants.ts index b8c420e43..52b95a1de 100644 --- a/src/web/client/common/constants.ts +++ b/src/web/client/common/constants.ts @@ -71,6 +71,7 @@ export enum queryParameters { ENV_ID = "envid", GEO = "geo", ENABLE_MULTIFILE = "enablemultifile", + WEBSITE_PREVIEW_URL = "websitepreviewurl" } export enum httpMethod { diff --git a/src/web/client/extension.ts b/src/web/client/extension.ts index 5a1a336be..c8afe0716 100644 --- a/src/web/client/extension.ts +++ b/src/web/client/extension.ts @@ -30,6 +30,7 @@ import { } from "./utilities/fileAndEntityUtil"; import { IEntityInfo } from "./common/interfaces"; import { telemetryEventNames } from "./telemetry/constants"; +import { PowerPagesNavigationProvider } from "./webViews/powerPagesNavigationProvider"; export function activate(context: vscode.ExtensionContext): void { // setup telemetry @@ -119,6 +120,8 @@ export function activate(context: vscode.ExtensionContext): void { processWalkthroughFirstRunExperience(context); + powerPagesNavigation(); + await vscode.window.withProgress( { location: vscode.ProgressLocation.Notification, @@ -180,6 +183,13 @@ export function activate(context: vscode.ExtensionContext): void { showWalkthrough(context, WebExtensionContext.telemetry); } +export function powerPagesNavigation() { + const powerPagesNavigationProvider = new PowerPagesNavigationProvider(); + vscode.window.registerTreeDataProvider('powerPagesFileExplorer', powerPagesNavigationProvider); + vscode.commands.registerCommand('powerPagesFileExplorer.previewPowerPages', () => powerPagesNavigationProvider.previewPowerPageSite()); + vscode.commands.registerCommand('powerPagesFileExplorer.backToStudio', () => powerPagesNavigationProvider.backToStudio()); +} + export function processWalkthroughFirstRunExperience(context: vscode.ExtensionContext) { const isMultifileFirstRun = context.globalState.get( IS_MULTIFILE_FIRST_RUN_EXPERIENCE, diff --git a/src/web/client/webViews/powerPagesNavigationProvider.ts b/src/web/client/webViews/powerPagesNavigationProvider.ts new file mode 100644 index 000000000..6f595a4b2 --- /dev/null +++ b/src/web/client/webViews/powerPagesNavigationProvider.ts @@ -0,0 +1,138 @@ +/* + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + */ + +import * as vscode from 'vscode'; +import * as path from 'path'; +import WebExtensionContext from "../WebExtensionContext"; +import { httpMethod, queryParameters } from '../common/constants'; +//import { getCommonHeaders } from '../common/authenticationProvider'; + +export class PowerPagesNavigationProvider implements vscode.TreeDataProvider { + + private _onDidChangeTreeData: vscode.EventEmitter = new vscode.EventEmitter(); + readonly onDidChangeTreeData: vscode.Event = this._onDidChangeTreeData.event; + + refresh(): void { + this._onDidChangeTreeData.fire(); + } + + getTreeItem(element: PowerPagesNode): vscode.TreeItem { + return element; + } + + getChildren(element?: PowerPagesNode): Thenable { + if (element) { + return Promise.resolve(this.getNodes(path.join(element.label))); + } else { + return Promise.resolve(this.getNodes()); + } + } + + getNodes(label?: string): PowerPagesNode[] { + const nodes: PowerPagesNode[] = []; + const previewPowerPage = new PowerPagesNode('Show site in new tab', + { + command: 'powerPagesFileExplorer.previewPowerPages', + title: '', + arguments: [] + }); + const backToStudio = new PowerPagesNode('Open powerpages', + { + command: 'powerPagesFileExplorer.backToStudio', + title: '', + arguments: [] + }); + + console.log(path.join(__filename, '..', '..', 'src', 'web', 'client', 'assets', 'backToStudio.svg')); + + if (label && label === previewPowerPage.label) { + nodes.push(previewPowerPage); + } else if (label && label === backToStudio.label) { + nodes.push(backToStudio); + } else { + nodes.push(previewPowerPage); + nodes.push(backToStudio); + } + + return nodes; + } + + async previewPowerPageSite(): Promise { + let requestSentAtTime = new Date().getTime(); + // TODO: implement + console.log("Execute preview power pages site", WebExtensionContext.urlParametersMap.get(queryParameters.WEBSITE_PREVIEW_URL) as string); + + // Runtime clear cache call + const requestUrl = "https://site-e1qvm.powerappsportals.com/_services/portal/5f518837-2ee2-4fd6-9c21-a4bfb8b8f699/invalidate-cache-maker?portalId=5f518837-2ee2-4fd6-9c21-a4bfb8b8f699&multiTenantPortalUrl=https:%2F%2Fsite-e1qvm.prod-us-il0201-1.tip.powerappsmtportals.com&runTimePortalUrl=https:%2F%2Fsite-e1qvm.powerappsportals.com&orgId=1e2468b8-e925-ee11-8476-00224820c64c&instanceUrl=https:%2F%2Forgd07539e4.crm10.dynamics.com%2F"; + + WebExtensionContext.telemetry.sendAPITelemetry( + requestUrl, + "Preview power pages site", + httpMethod.POST, + this.previewPowerPageSite.name + ); + requestSentAtTime = new Date().getTime(); + WebExtensionContext.dataverseAuthentication(); + + const response = await WebExtensionContext.concurrencyHandler.handleRequest(requestUrl, { + // headers: getCommonHeaders(WebExtensionContext.dataverseAccessToken), + headers: { + authorization: "Bearer " + WebExtensionContext.dataverseAccessToken, + "Access-Control-Allow-Origin": "*", + "Access-Control-Allow-Methods": "DELETE, POST, GET, OPTIONS", + "Access-Control-Allow-Headers": "Content-Type, Authorization, X-Requested-With" + } + }); + + if (response.ok) { + WebExtensionContext.telemetry.sendAPISuccessTelemetry( + requestUrl, + "Preview power pages site", + httpMethod.POST, + new Date().getTime() - requestSentAtTime, + this.previewPowerPageSite.name + ); + } else { + WebExtensionContext.telemetry.sendAPIFailureTelemetry( + requestUrl, + "Preview power pages site", + httpMethod.POST, + new Date().getTime() - requestSentAtTime, + this.previewPowerPageSite.name, + JSON.stringify(response), + '', + response?.status.toString() + ); + } + + + vscode.env.openExternal(vscode.Uri.parse(WebExtensionContext.urlParametersMap.get(queryParameters.WEBSITE_PREVIEW_URL) as string)); + } + + backToStudio(): void { + // TODO: implement + console.log("Execute back to studio"); + vscode.env.openExternal(vscode.Uri.parse("https://make.test.powerpages.microsoft.com/e/5b6338ff-aa3e-ecd4-a8ab-1d48fda1e109/sites/b17443f1-f825-ee11-bdf4-0022481d5eb9/pages")); + } +} + + + +export class PowerPagesNode extends vscode.TreeItem { + constructor( + public readonly label: string, + public readonly command?: vscode.Command + ) { + super(label, vscode.TreeItemCollapsibleState.None); + + this.tooltip = this.label; + this.command = command; + } + + iconPath = { + light: path.join(__filename, '..', '..', 'src', 'web', 'client', 'assets', 'backToStudio.svg'), + dark: path.join(__filename, '..', '..', 'src', 'web', 'client', 'assets', 'powerPages.svg') + }; +} \ No newline at end of file From c7e5d8b7e40bbdd96e1c8feceb2c9d7a72ea73dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nidhi=20Tyagi=20=F0=9F=8C=9F=F0=9F=90=87=F0=9F=8C=B4?= =?UTF-8?q?=E2=9D=84=EF=B8=8F?= Date: Thu, 3 Aug 2023 16:42:20 +0530 Subject: [PATCH 2/9] update for new org and test calls to runtime --- .../client/webViews/powerPagesNavigationProvider.ts | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/web/client/webViews/powerPagesNavigationProvider.ts b/src/web/client/webViews/powerPagesNavigationProvider.ts index 6f595a4b2..1f4252047 100644 --- a/src/web/client/webViews/powerPagesNavigationProvider.ts +++ b/src/web/client/webViews/powerPagesNavigationProvider.ts @@ -65,7 +65,7 @@ export class PowerPagesNavigationProvider implements vscode.TreeDataProvider Date: Fri, 4 Aug 2023 11:31:39 +0530 Subject: [PATCH 3/9] headers change --- src/web/client/webViews/powerPagesNavigationProvider.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/web/client/webViews/powerPagesNavigationProvider.ts b/src/web/client/webViews/powerPagesNavigationProvider.ts index 1f4252047..5fb7a29df 100644 --- a/src/web/client/webViews/powerPagesNavigationProvider.ts +++ b/src/web/client/webViews/powerPagesNavigationProvider.ts @@ -81,7 +81,10 @@ export class PowerPagesNavigationProvider implements vscode.TreeDataProvider Date: Thu, 10 Aug 2023 12:12:19 +0530 Subject: [PATCH 4/9] Update to config API --- src/web/client/common/constants.ts | 1 + .../webViews/powerPagesNavigationProvider.ts | 24 +++++++++++-------- 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/src/web/client/common/constants.ts b/src/web/client/common/constants.ts index 52b95a1de..0eb2ffafc 100644 --- a/src/web/client/common/constants.ts +++ b/src/web/client/common/constants.ts @@ -78,6 +78,7 @@ export enum httpMethod { PATCH = "PATCH", GET = "GET", POST = "POST", + DELETE = "DELETE", } export enum SurveyConstants { diff --git a/src/web/client/webViews/powerPagesNavigationProvider.ts b/src/web/client/webViews/powerPagesNavigationProvider.ts index 5fb7a29df..cebceba02 100644 --- a/src/web/client/webViews/powerPagesNavigationProvider.ts +++ b/src/web/client/webViews/powerPagesNavigationProvider.ts @@ -65,12 +65,14 @@ export class PowerPagesNavigationProvider implements vscode.TreeDataProvider Date: Fri, 29 Sep 2023 15:25:41 +0530 Subject: [PATCH 5/9] Add svg and make entire loop work --- package.json | 22 ++-- src/web/client/WebExtensionContext.ts | 10 +- src/web/client/common/constants.ts | 2 + src/web/client/extension.ts | 9 +- src/web/client/utilities/commonUtil.ts | 21 ++- src/web/client/webViews/NPSWebView.ts | 5 +- .../webViews/powerPagesNavigationProvider.ts | 124 +++++++++--------- 7 files changed, 107 insertions(+), 86 deletions(-) diff --git a/package.json b/package.json index a31ca8233..a7916676c 100644 --- a/package.json +++ b/package.json @@ -154,11 +154,11 @@ ], "commands": [ { - "command": "powerPagesFileExplorer.previewPowerPages", + "command": "powerpages.powerPagesFileExplorer.powerPagesRuntimePreview", "title": "Preview Power Pages site" }, { - "command": "powerPagesFileExplorer.backToStudio", + "command": "powerpages.powerPagesFileExplorer.backToStudio", "title": "Back to Studio" }, { @@ -868,18 +868,12 @@ ], "explorer": [ { - "id": "powerpages.treeWebView", - "name": "Power Pages Actions", - "when": "isWeb && config.powerPlatform.experimental.enableCoPresenceFeature" - } - ], - "explorer": [ - { - "id": "powerPagesFileExplorer", - "name": "POWERPAGE", + "id": "powerpages.powerPagesFileExplorer", + "name": "POWER PAGES ACTIONS", "when": "isWeb && virtualWorkspace", - "icon": "src/web/client/assets/powerPages.svg", - "contextualTitle": "Power Pages" + "icon": "./src/web/client/assets/powerPages.svg", + "contextualTitle": "Power Pages Actions", + "visibility": "visible" } ] }, @@ -984,9 +978,9 @@ "jwt-decode": "2.2.0", "mocha": "^9.2.2", "moment": "^2.29.4", + "nanoid": "^3.1.31", "node-fetch": "^2.6.7", "nyc": "^15.1.0", - "nanoid": "^3.1.31", "os-browserify": "^0.3.0", "path-browserify": "^1.0.1", "process": "^0.11.10", diff --git a/src/web/client/WebExtensionContext.ts b/src/web/client/WebExtensionContext.ts index 6d975b018..dccfa2826 100644 --- a/src/web/client/WebExtensionContext.ts +++ b/src/web/client/WebExtensionContext.ts @@ -56,6 +56,7 @@ export interface IWebExtensionContext { defaultFileUri: vscode.Uri; // This will default to home page or current page in multifile scenario showMultifileInVSCode: boolean; extensionActivationTime: number; + extensionUri: vscode.Uri // Org specific details dataverseAccessToken: string; @@ -90,6 +91,7 @@ class WebExtensionContext implements IWebExtensionContext { private _defaultFileUri: vscode.Uri; private _showMultifileInVSCode: boolean; private _extensionActivationTime: number; + private _extensionUri: vscode.Uri; private _dataverseAccessToken: string; private _entityDataMap: EntityDataMap; private _isContextSet: boolean; @@ -149,6 +151,9 @@ class WebExtensionContext implements IWebExtensionContext { public get extensionActivationTime() { return this._extensionActivationTime } + public get extensionUri() { + return this._extensionUri + } public get dataverseAccessToken() { return this._dataverseAccessToken; } @@ -199,6 +204,7 @@ class WebExtensionContext implements IWebExtensionContext { this._defaultFileUri = vscode.Uri.parse(``); this._showMultifileInVSCode = false; this._extensionActivationTime = new Date().getTime(); + this._extensionUri = vscode.Uri.parse(""); this._isContextSet = false; this._currentSchemaVersion = ""; this._websiteLanguageCode = ""; @@ -212,7 +218,8 @@ class WebExtensionContext implements IWebExtensionContext { public setWebExtensionContext( entityName: string, entityId: string, - queryParamsMap: Map + queryParamsMap: Map, + extensionUri?: vscode.Uri ) { const schema = queryParamsMap.get(schemaKey.SCHEMA_VERSION) as string; // Initialize context from URL params @@ -227,6 +234,7 @@ class WebExtensionContext implements IWebExtensionContext { }/`, true ); + this._extensionUri = extensionUri as vscode.Uri; // Initialize multifile FF here const enableMultifile = queryParamsMap?.get(Constants.queryParameters.ENABLE_MULTIFILE); diff --git a/src/web/client/common/constants.ts b/src/web/client/common/constants.ts index eff9bcf53..f11a2358a 100644 --- a/src/web/client/common/constants.ts +++ b/src/web/client/common/constants.ts @@ -26,6 +26,8 @@ export const MAX_ENTITY_FETCH_COUNT = 100; export const MAX_CONCURRENT_REQUEST_COUNT = 50; export const MAX_CONCURRENT_REQUEST_QUEUE_COUNT = 1000; export const INTELLIGENCE_SCOPE_DEFAULT = "https://text.pai.dynamics.com/.default"; +export const BACK_TO_STUDIO_URL_TEMPLATE = "https://make{.region}.powerpages.microsoft.com/e/{environmentId}/sites/{webSiteId}/pages"; +export const STUDIO_PROD_REGION = "prod"; // Web extension constants export const BASE_64 = 'base64'; diff --git a/src/web/client/extension.ts b/src/web/client/extension.ts index 44af77321..9e5c7cc68 100644 --- a/src/web/client/extension.ts +++ b/src/web/client/extension.ts @@ -103,7 +103,8 @@ export function activate(context: vscode.ExtensionContext): void { WebExtensionContext.setWebExtensionContext( entity, entityId, - queryParamsMap + queryParamsMap, + context.extensionUri ); WebExtensionContext.setVscodeWorkspaceState(context.workspaceState); WebExtensionContext.telemetry.sendExtensionInitPathParametersTelemetry( @@ -192,9 +193,9 @@ export function activate(context: vscode.ExtensionContext): void { export function powerPagesNavigation() { const powerPagesNavigationProvider = new PowerPagesNavigationProvider(); - vscode.window.registerTreeDataProvider('powerPagesFileExplorer', powerPagesNavigationProvider); - vscode.commands.registerCommand('powerPagesFileExplorer.previewPowerPages', () => powerPagesNavigationProvider.previewPowerPageSite()); - vscode.commands.registerCommand('powerPagesFileExplorer.backToStudio', () => powerPagesNavigationProvider.backToStudio()); + vscode.window.registerTreeDataProvider('powerpages.powerPagesFileExplorer', powerPagesNavigationProvider); + vscode.commands.registerCommand('powerpages.powerPagesFileExplorer.powerPagesRuntimePreview', () => powerPagesNavigationProvider.previewPowerPageSite()); + vscode.commands.registerCommand('powerpages.powerPagesFileExplorer.backToStudio', () => powerPagesNavigationProvider.backToStudio()); } export function processWalkthroughFirstRunExperience(context: vscode.ExtensionContext) { diff --git a/src/web/client/utilities/commonUtil.ts b/src/web/client/utilities/commonUtil.ts index eeb235be6..aac3829c6 100644 --- a/src/web/client/utilities/commonUtil.ts +++ b/src/web/client/utilities/commonUtil.ts @@ -5,13 +5,16 @@ import * as vscode from "vscode"; import { + BACK_TO_STUDIO_URL_TEMPLATE, BASE_64, CO_PRESENCE_FEATURE_SETTING_NAME, DATA, MULTI_FILE_FEATURE_SETTING_NAME, NO_CONTENT, + STUDIO_PROD_REGION, VERSION_CONTROL_FOR_WEB_EXTENSION_SETTING_NAME, - portalSchemaVersion + portalSchemaVersion, + queryParameters } from "../common/constants"; import { IAttributePath } from "../common/interfaces"; import { schemaEntityName } from "../schema/constants"; @@ -199,10 +202,24 @@ export function isPortalVersionV2(): boolean { return WebExtensionContext.currentSchemaVersion.toLowerCase() === portalSchemaVersion.V2; } -export function getWorkSpaceName(websiteId : string) : string { +export function getWorkSpaceName(websiteId: string): string { if (isPortalVersionV1()) { return `Site-v1-${websiteId}`; } else { return `Site-v2-${websiteId}`; } } + +// ENV_ID is the last part of the parameter value sent in the vscode URL from studio +export function getEnvironmentIdFromUrl() { + return (WebExtensionContext.urlParametersMap.get(queryParameters.ENV_ID) as string).split("/")?.pop() as string; +} + +export function getBackToStudioURL() { + const region = WebExtensionContext.urlParametersMap.get(queryParameters.REGION) as string; + + return BACK_TO_STUDIO_URL_TEMPLATE + .replace("{environmentId}", getEnvironmentIdFromUrl()) + .replace("{.region}", region.toLowerCase() === STUDIO_PROD_REGION ? "" : `.${WebExtensionContext.urlParametersMap.get(queryParameters.REGION) as string}`) + .replace("{webSiteId}", WebExtensionContext.urlParametersMap.get(queryParameters.WEBSITE_ID) as string); +} diff --git a/src/web/client/webViews/NPSWebView.ts b/src/web/client/webViews/NPSWebView.ts index 1cf3930cf..35fcdb404 100644 --- a/src/web/client/webViews/NPSWebView.ts +++ b/src/web/client/webViews/NPSWebView.ts @@ -8,6 +8,7 @@ import WebExtensionContext from "../WebExtensionContext"; import { queryParameters } from "../common/constants"; import { getDeviceType } from "../utilities/deviceType"; import { telemetryEventNames } from "../telemetry/constants"; +import { getEnvironmentIdFromUrl } from "../utilities/commonUtil"; export class NPSWebView { private readonly _webviewPanel: vscode.WebviewPanel; @@ -27,9 +28,7 @@ export class NPSWebView { const tid = WebExtensionContext.urlParametersMap?.get( queryParameters.TENANT_ID ); - const envId = WebExtensionContext.urlParametersMap - ?.get(queryParameters.ENV_ID) - ?.split("/")[4]; + const envId = getEnvironmentIdFromUrl(); const geo = WebExtensionContext.urlParametersMap?.get( queryParameters.GEO ); diff --git a/src/web/client/webViews/powerPagesNavigationProvider.ts b/src/web/client/webViews/powerPagesNavigationProvider.ts index cebceba02..34b7b3943 100644 --- a/src/web/client/webViews/powerPagesNavigationProvider.ts +++ b/src/web/client/webViews/powerPagesNavigationProvider.ts @@ -7,7 +7,7 @@ import * as vscode from 'vscode'; import * as path from 'path'; import WebExtensionContext from "../WebExtensionContext"; import { httpMethod, queryParameters } from '../common/constants'; -//import { getCommonHeaders } from '../common/authenticationProvider'; +import { getBackToStudioURL } from '../utilities/commonUtil'; export class PowerPagesNavigationProvider implements vscode.TreeDataProvider { @@ -32,20 +32,20 @@ export class PowerPagesNavigationProvider implements vscode.TreeDataProvider { let requestSentAtTime = new Date().getTime(); - // TODO: implement - console.log("Execute preview power pages site", WebExtensionContext.urlParametersMap.get(queryParameters.WEBSITE_PREVIEW_URL) as string); - + const websitePreviewUrl = WebExtensionContext.urlParametersMap.get(queryParameters.WEBSITE_PREVIEW_URL) as string; // Runtime clear cache call - //const requestUrl = "https://site-npeby.powerappsportals.com/_services/portal/547f0b36-0ad2-446f-9543-99effc6fce8e/invalidate-cache-maker"; - const requestUrl = "https://site-npeby.powerappsportals.com/_services/cache/config"; + const requestUrl = `${websitePreviewUrl.endsWith('/') ? websitePreviewUrl : websitePreviewUrl.concat('/')}_services/cache/config`; WebExtensionContext.telemetry.sendAPITelemetry( requestUrl, "Preview power pages site", - //httpMethod.POST, httpMethod.DELETE, this.previewPowerPageSite.name ); requestSentAtTime = new Date().getTime(); WebExtensionContext.dataverseAuthentication(); - const response = await WebExtensionContext.concurrencyHandler.handleRequest(requestUrl, { - // headers: getCommonHeaders(WebExtensionContext.dataverseAccessToken), - headers: { - authorization: "Bearer " + WebExtensionContext.dataverseAccessToken, - 'Accept': '*/*', - 'Content-Type': 'text/plain', - //'orgId': WebExtensionContext.urlParametersMap.get(queryParameters.ORG_ID), - //'referrer-policy': 'strict-origin-when-cross-origin', - //'origin': 'https://v--1p5gunfsmqb4gsdpnrjapmdv61ofml3sahb9pd8de82ruqv7m773.vscode-cdn.net/' - // 'Access-Control-Allow-Origin': '*', - // 'Access-Control-Allow-Headers': 'access-control-allow-origin,authorization,content-type,referrer-policy' + await vscode.window.withProgress( + { + location: vscode.ProgressLocation.Notification, + cancellable: true, + title: vscode.l10n.t("Opening preview site..."), }, - method: 'DELETE', - // body: JSON.stringify({ - // runtimeInvalidationRequest: "{\"entities\":[{\"entityName\":\"*\"}],\"source\":\"\"}" - // }) - }); - - if (response.ok) { - WebExtensionContext.telemetry.sendAPISuccessTelemetry( - requestUrl, - "Preview power pages site", - httpMethod.DELETE, - new Date().getTime() - requestSentAtTime, - this.previewPowerPageSite.name - ); - } else { - WebExtensionContext.telemetry.sendAPIFailureTelemetry( - requestUrl, - "Preview power pages site", - httpMethod.DELETE, - new Date().getTime() - requestSentAtTime, - this.previewPowerPageSite.name, - JSON.stringify(response), - '', - response?.status.toString() - ); - } - + async () => { + const response = await WebExtensionContext.concurrencyHandler.handleRequest(requestUrl, { + headers: { + authorization: "Bearer " + WebExtensionContext.dataverseAccessToken, + 'Accept': '*/*', + 'Content-Type': 'text/plain', + }, + method: 'DELETE', + }); + + if (response.ok) { + WebExtensionContext.telemetry.sendAPISuccessTelemetry( + requestUrl, + "Preview power pages site", + httpMethod.DELETE, + new Date().getTime() - requestSentAtTime, + this.previewPowerPageSite.name + ); + } else { + WebExtensionContext.telemetry.sendAPIFailureTelemetry( + requestUrl, + "Preview power pages site", + httpMethod.DELETE, + new Date().getTime() - requestSentAtTime, + this.previewPowerPageSite.name, + JSON.stringify(response), + '', + response?.status.toString() + ); + } + + + } + ); - vscode.env.openExternal(vscode.Uri.parse(WebExtensionContext.urlParametersMap.get(queryParameters.WEBSITE_PREVIEW_URL) as string)); + vscode.env.openExternal(vscode.Uri.parse(websitePreviewUrl)); } backToStudio(): void { - // TODO: implement - console.log("Execute back to studio"); - vscode.env.openExternal(vscode.Uri.parse("https://make.test.powerpages.microsoft.com/e/5b6338ff-aa3e-ecd4-a8ab-1d48fda1e109/sites/b17443f1-f825-ee11-bdf4-0022481d5eb9/pages")); + vscode.env.openExternal(vscode.Uri.parse(getBackToStudioURL())); } } @@ -133,16 +128,21 @@ export class PowerPagesNavigationProvider implements vscode.TreeDataProvider Date: Fri, 29 Sep 2023 16:20:08 +0530 Subject: [PATCH 6/9] Add telemetry events --- src/web/client/extension.ts | 1 + src/web/client/telemetry/constants.ts | 4 ++++ .../client/webViews/powerPagesNavigationProvider.ts | 11 ++++++++--- 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/src/web/client/extension.ts b/src/web/client/extension.ts index 9e5c7cc68..42142cc19 100644 --- a/src/web/client/extension.ts +++ b/src/web/client/extension.ts @@ -196,6 +196,7 @@ export function powerPagesNavigation() { vscode.window.registerTreeDataProvider('powerpages.powerPagesFileExplorer', powerPagesNavigationProvider); vscode.commands.registerCommand('powerpages.powerPagesFileExplorer.powerPagesRuntimePreview', () => powerPagesNavigationProvider.previewPowerPageSite()); vscode.commands.registerCommand('powerpages.powerPagesFileExplorer.backToStudio', () => powerPagesNavigationProvider.backToStudio()); + WebExtensionContext.telemetry.sendInfoTelemetry(telemetryEventNames.WEB_EXTENSION_POWER_PAGES_WEB_VIEW_REGISTERED); } export function processWalkthroughFirstRunExperience(context: vscode.ExtensionContext) { diff --git a/src/web/client/telemetry/constants.ts b/src/web/client/telemetry/constants.ts index e7ca18d36..b2a2ade42 100644 --- a/src/web/client/telemetry/constants.ts +++ b/src/web/client/telemetry/constants.ts @@ -93,4 +93,8 @@ export enum telemetryEventNames { WEB_EXTENSION_WEB_COPILOT_REGISTRATION_FAILED = 'webExtensionCopilotRegisterFailed', WEB_EXTENSION_WEB_COPILOT_NOTIFICATION_SHOWN = 'webExtensionCopilotNotificationShown', WEB_EXTENSION_WEB_COPILOT_NOTIFICATION_EVENT_CLICKED = 'webExtensionCopilotNotificationEventClicked', + WEB_EXTENSION_POWER_PAGES_WEB_VIEW_REGISTERED = 'webExtensionPowerPagesWebViewRegistered', + WEB_EXTENSION_POWER_PAGES_WEB_VIEW_REGISTER_FAILED = 'webExtensionPowerPagesWebViewRegisterFailed', + WEB_EXTENSION_BACK_TO_STUDIO_TRIGGERED = 'webExtensionBackToStudioTriggered', + WEB_EXTENSION_PREVIEW_SITE_TRIGGERED = 'webExtensionPreviewSiteTriggered', } diff --git a/src/web/client/webViews/powerPagesNavigationProvider.ts b/src/web/client/webViews/powerPagesNavigationProvider.ts index 34b7b3943..7312dbeb0 100644 --- a/src/web/client/webViews/powerPagesNavigationProvider.ts +++ b/src/web/client/webViews/powerPagesNavigationProvider.ts @@ -8,6 +8,7 @@ import * as path from 'path'; import WebExtensionContext from "../WebExtensionContext"; import { httpMethod, queryParameters } from '../common/constants'; import { getBackToStudioURL } from '../utilities/commonUtil'; +import { telemetryEventNames } from '../telemetry/constants'; export class PowerPagesNavigationProvider implements vscode.TreeDataProvider { @@ -116,15 +117,19 @@ export class PowerPagesNavigationProvider implements vscode.TreeDataProvider Date: Tue, 3 Oct 2023 13:20:56 +0530 Subject: [PATCH 7/9] Make commands unavailable in command palette --- package.json | 6 ++++-- src/web/client/webViews/powerPagesNavigationProvider.ts | 1 - 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index 70631769b..85f55104a 100644 --- a/package.json +++ b/package.json @@ -155,11 +155,13 @@ "commands": [ { "command": "powerpages.powerPagesFileExplorer.powerPagesRuntimePreview", - "title": "Preview Power Pages site" + "title": "Preview Power Pages site", + "when": "never" }, { "command": "powerpages.powerPagesFileExplorer.backToStudio", - "title": "Back to Studio" + "title": "Back to Studio", + "when": "never" }, { "command": "extension.createChatView", diff --git a/src/web/client/webViews/powerPagesNavigationProvider.ts b/src/web/client/webViews/powerPagesNavigationProvider.ts index 7312dbeb0..f8636a201 100644 --- a/src/web/client/webViews/powerPagesNavigationProvider.ts +++ b/src/web/client/webViews/powerPagesNavigationProvider.ts @@ -144,7 +144,6 @@ export class PowerPagesNode extends vscode.TreeItem { } getIconPath(svgFileName: string) { - console.log(WebExtensionContext.extensionUri, vscode.Uri.joinPath(WebExtensionContext.extensionUri, '..', '..', 'src', 'web', 'client', 'assets', svgFileName)); return { light: vscode.Uri.joinPath(WebExtensionContext.extensionUri, '..', '..', 'src', 'web', 'client', 'assets', svgFileName), dark: vscode.Uri.joinPath(WebExtensionContext.extensionUri, '..', '..', 'src', 'web', 'client', 'assets', svgFileName) From a51fa24ac255d4fb4d2a37801ea1e04756bc6fdc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nidhi=20Tyagi=20=F0=9F=8C=9F=F0=9F=90=87=F0=9F=8C=B4?= =?UTF-8?q?=E2=9D=84=EF=B8=8F?= Date: Tue, 3 Oct 2023 23:08:46 +0530 Subject: [PATCH 8/9] Add localized strings for the explorer visible text --- l10n/bundle.l10n.json | 3 +-- .../vscode-powerplatform.xlf | 18 +++++++++----- package.json | 8 +++---- package.nls.json | 24 ++++++++++--------- 4 files changed, 30 insertions(+), 23 deletions(-) diff --git a/l10n/bundle.l10n.json b/l10n/bundle.l10n.json index 5e4beea75..83248b899 100644 --- a/l10n/bundle.l10n.json +++ b/l10n/bundle.l10n.json @@ -5,8 +5,7 @@ "Edit the site": "Edit the site", "Be careful making changes. Anyone can see the changes you make immediately. Choose Edit the site to make edits, or close the editor tab to cancel without editing.": "Be careful making changes. Anyone can see the changes you make immediately. Choose Edit the site to make edits, or close the editor tab to cancel without editing.", "You are editing a live, public site ": "You are editing a live, public site ", - "Get help writing code in HTML, CSS, and JS languages for Power Pages sites with Copilot.": "Get help writing code in HTML, CSS, and JS languages for Power Pages sites with Copilot.", - "Try Copilot for Power Pages": "Try Copilot for Power Pages", + "Opening preview site...": "Opening preview site...", "Microsoft wants your feeback": "Microsoft wants your feeback", "Check the URL and verify the parameters are correct": "Check the URL and verify the parameters are correct", "Unable to complete the request": "Unable to complete the request", diff --git a/loc/translations-export/vscode-powerplatform.xlf b/loc/translations-export/vscode-powerplatform.xlf index 358a0994f..cfacfafb5 100644 --- a/loc/translations-export/vscode-powerplatform.xlf +++ b/loc/translations-export/vscode-powerplatform.xlf @@ -121,9 +121,6 @@ The {3} represents Solution's Type (Managed or Unmanaged), but that test is loca File(s) already exist. No new files to add - - Get help writing code in HTML, CSS, and JS languages for Power Pages sites with Copilot. - Installing Power Pages generator(v{0})... {0} represents the version number @@ -182,6 +179,9 @@ The {3} represents Dataverse Environment's Organization ID (GUID) One or more attribute names have been changed or removed. Contact your admin. + + Opening preview site... + PAC Telemetry disabled @@ -247,9 +247,6 @@ The {3} represents Dataverse Environment's Organization ID (GUID) There’s a problem on the back end - - Try Copilot for Power Pages - Try again @@ -301,6 +298,9 @@ To learn more, visit [Prevent accidental overwrites](command:powerplatform-walkt This is a Markdown formatted string, and the formatting must persist across translations. The fifth line should be '[TRANSLATION HERE](command:powerplatform-walkthrough.saveConflict-learn-more).', keeping brackets and the text in the parentheses unmodified + + Back to Studio + Clear Auth Profiles @@ -407,12 +407,18 @@ The second line should be '[TRANSLATION HERE](command:powerplatform-walkthrough. Overview + + POWER PAGES ACTIONS + Power Platform PowerApps Portal -> Show preview + + Preview Power Pages site + Refresh diff --git a/package.json b/package.json index ff50859ef..a1520ee58 100644 --- a/package.json +++ b/package.json @@ -155,12 +155,12 @@ "commands": [ { "command": "powerpages.powerPagesFileExplorer.powerPagesRuntimePreview", - "title": "Preview Power Pages site", + "title": "%microsoft-powerplatform-portals.navigation-loop.previewSite.title%", "when": "never" }, { "command": "powerpages.powerPagesFileExplorer.backToStudio", - "title": "Back to Studio", + "title": "%microsoft-powerplatform-portals.navigation-loop.backToStudio.title%", "when": "never" }, { @@ -897,10 +897,10 @@ "explorer": [ { "id": "powerpages.powerPagesFileExplorer", - "name": "POWER PAGES ACTIONS", + "name": "%microsoft-powerplatform-portals.navigation-loop.powerPagesFileExplorer.title%", "when": "isWeb && virtualWorkspace", "icon": "./src/web/client/assets/powerPages.svg", - "contextualTitle": "Power Pages Actions", + "contextualTitle": "%microsoft-powerplatform-portals.navigation-loop.powerPagesFileExplorer.title%", "visibility": "visible" } ] diff --git a/package.nls.json b/package.nls.json index 0ade7e5e4..f8f4fa402 100644 --- a/package.nls.json +++ b/package.nls.json @@ -13,10 +13,10 @@ "pacCLI.authPanel.title": "Auth Profiles", "pacCLI.authPanel.welcome.whenInteractiveSupported": { - "message": "No auth profiles found on this computer.\n[Add Auth Profile](command:pacCLI.authPanel.newAuthProfile)", - "comment": [ - "This is a Markdown formatted string, and the formatting must persist across translations.", - "The second line should be '[TRANSLATION HERE](command:pacCLI.authPanel.newAuthProfile)', keeping brackets and the text in the parentheses unmodified" + "message": "No auth profiles found on this computer.\n[Add Auth Profile](command:pacCLI.authPanel.newAuthProfile)", + "comment": [ + "This is a Markdown formatted string, and the formatting must persist across translations.", + "The second line should be '[TRANSLATION HERE](command:pacCLI.authPanel.newAuthProfile)', keeping brackets and the text in the parentheses unmodified" ] }, "pacCLI.authPanel.welcome.whenInteractiveNotSupported": { @@ -25,8 +25,7 @@ "This is a Markdown formatted string, and the formatting must persist across translations.", "The second line should not translate the argument `--deviceCode`", "The third line should be '[TRANSLATION HERE](command:pacCLI.pacAuthHelp)', keeping brackets and the text in the parentheses unmodified" - - ] + ] }, "pacCLI.authPanel.clearAuthProfile.title": "Clear Auth Profiles", "pacCLI.authPanel.refresh.title": "Refresh", @@ -67,7 +66,7 @@ "comment": [ "This is a Markdown formatted string, and the formatting must persist across translations.", "The second line should be '[TRANSLATION HERE](command:powerplatform-walkthrough.overview-learn-more)', keeping brackets and the text in the parentheses unmodified" - ] + ] }, "microsoft-powerapps-portals.walkthrough.fileSystem.title": "File explorer", "microsoft-powerapps-portals.walkthrough.fileSystem.description": { @@ -76,7 +75,7 @@ "This is a Markdown formatted string, and the formatting must persist across translations.", "The seventh line should be '[TRANSLATION HERE](command:powerplatform-walkthrough.fileSystem-documentation).', keeping brackets and the text in the parentheses unmodified", "The eighth line should be '[TRANSLATION HERE](command:powerplatform-walkthrough.fileSystem-open-folder)', keeping brackets and the text in the parentheses unmodified" - ] + ] }, "microsoft-powerapps-portals.walkthrough.advancedCapabilities.title": "Advanced capabilities", "microsoft-powerapps-portals.walkthrough.advancedCapabilities.description": { @@ -85,7 +84,7 @@ "This is a Markdown formatted string, and the formatting must persist across translations.", "The fifth line should be '[TRANSLATION HERE](command:powerplatform-walkthrough.advancedCapabilities-learn-more) TRANSLATION', keeping brackets and the text in the parentheses unmodified", "The seventh line should be '[TRANSLATION HERE](command:powerplatform-walkthrough.advancedCapabilities-start-coding)', keeping brackets and the text in the parentheses unmodified" - ] + ] }, "microsoft-powerapps-portals.walkthrough.saveConflict.title": "Save conflict", "microsoft-powerapps-portals.walkthrough.saveConflict.description": { @@ -93,6 +92,9 @@ "comment": [ "This is a Markdown formatted string, and the formatting must persist across translations.", "The fifth line should be '[TRANSLATION HERE](command:powerplatform-walkthrough.saveConflict-learn-more).', keeping brackets and the text in the parentheses unmodified" - ] - } + ] + }, + "microsoft-powerplatform-portals.navigation-loop.backToStudio.title": "Back to Studio", + "microsoft-powerplatform-portals.navigation-loop.previewSite.title": "Preview Power Pages site", + "microsoft-powerplatform-portals.navigation-loop.powerPagesFileExplorer.title": "POWER PAGES ACTIONS" } From 70b71b889b8c5a99b238df1f0e913ef58226735b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nidhi=20Tyagi=20=F0=9F=8C=9F=F0=9F=90=87=F0=9F=8C=B4?= =?UTF-8?q?=E2=9D=84=EF=B8=8F?= Date: Tue, 3 Oct 2023 23:41:41 +0530 Subject: [PATCH 9/9] Localize provider command text --- l10n/bundle.l10n.json | 2 ++ loc/translations-export/vscode-powerplatform.xlf | 12 ++++++------ package.json | 4 ++-- package.nls.json | 2 -- .../client/webViews/powerPagesNavigationProvider.ts | 8 ++++---- 5 files changed, 14 insertions(+), 14 deletions(-) diff --git a/l10n/bundle.l10n.json b/l10n/bundle.l10n.json index 83248b899..543eb689a 100644 --- a/l10n/bundle.l10n.json +++ b/l10n/bundle.l10n.json @@ -5,6 +5,8 @@ "Edit the site": "Edit the site", "Be careful making changes. Anyone can see the changes you make immediately. Choose Edit the site to make edits, or close the editor tab to cancel without editing.": "Be careful making changes. Anyone can see the changes you make immediately. Choose Edit the site to make edits, or close the editor tab to cancel without editing.", "You are editing a live, public site ": "You are editing a live, public site ", + "Preview site": "Preview site", + "Open in Power Pages": "Open in Power Pages", "Opening preview site...": "Opening preview site...", "Microsoft wants your feeback": "Microsoft wants your feeback", "Check the URL and verify the parameters are correct": "Check the URL and verify the parameters are correct", diff --git a/loc/translations-export/vscode-powerplatform.xlf b/loc/translations-export/vscode-powerplatform.xlf index cfacfafb5..a74eea106 100644 --- a/loc/translations-export/vscode-powerplatform.xlf +++ b/loc/translations-export/vscode-powerplatform.xlf @@ -179,6 +179,9 @@ The {3} represents Dataverse Environment's Organization ID (GUID) One or more attribute names have been changed or removed. Contact your admin. + + Open in Power Pages + Opening preview site... @@ -211,6 +214,9 @@ The {3} represents Dataverse Environment's Organization ID (GUID) Preparing pac CLI (v{0})... {0} represents the version number + + Preview site + Profile Kind: {0} The {0} represents the profile type (Admin vs Dataverse) @@ -298,9 +304,6 @@ To learn more, visit [Prevent accidental overwrites](command:powerplatform-walkt This is a Markdown formatted string, and the formatting must persist across translations. The fifth line should be '[TRANSLATION HERE](command:powerplatform-walkthrough.saveConflict-learn-more).', keeping brackets and the text in the parentheses unmodified - - Back to Studio - Clear Auth Profiles @@ -416,9 +419,6 @@ The second line should be '[TRANSLATION HERE](command:powerplatform-walkthrough. PowerApps Portal -> Show preview - - Preview Power Pages site - Refresh diff --git a/package.json b/package.json index a1520ee58..d7004a174 100644 --- a/package.json +++ b/package.json @@ -155,12 +155,12 @@ "commands": [ { "command": "powerpages.powerPagesFileExplorer.powerPagesRuntimePreview", - "title": "%microsoft-powerplatform-portals.navigation-loop.previewSite.title%", + "title": "Preview site", "when": "never" }, { "command": "powerpages.powerPagesFileExplorer.backToStudio", - "title": "%microsoft-powerplatform-portals.navigation-loop.backToStudio.title%", + "title": "Open in Power Pages", "when": "never" }, { diff --git a/package.nls.json b/package.nls.json index f8f4fa402..99f9a882d 100644 --- a/package.nls.json +++ b/package.nls.json @@ -94,7 +94,5 @@ "The fifth line should be '[TRANSLATION HERE](command:powerplatform-walkthrough.saveConflict-learn-more).', keeping brackets and the text in the parentheses unmodified" ] }, - "microsoft-powerplatform-portals.navigation-loop.backToStudio.title": "Back to Studio", - "microsoft-powerplatform-portals.navigation-loop.previewSite.title": "Preview Power Pages site", "microsoft-powerplatform-portals.navigation-loop.powerPagesFileExplorer.title": "POWER PAGES ACTIONS" } diff --git a/src/web/client/webViews/powerPagesNavigationProvider.ts b/src/web/client/webViews/powerPagesNavigationProvider.ts index f8636a201..34972a1b6 100644 --- a/src/web/client/webViews/powerPagesNavigationProvider.ts +++ b/src/web/client/webViews/powerPagesNavigationProvider.ts @@ -33,17 +33,17 @@ export class PowerPagesNavigationProvider implements vscode.TreeDataProvider