From 649c03f60952a7cb288cd915d7b42cb1fb7b92ec Mon Sep 17 00:00:00 2001 From: Priyanshu Agrawal Date: Tue, 21 Jan 2025 19:04:29 +0530 Subject: [PATCH 1/4] Web Extension: Remove dependency on website preview URL --- src/web/client/common/constants.ts | 1 - src/web/client/utilities/commonUtil.ts | 15 ++++++----- .../webViews/powerPagesNavigationProvider.ts | 27 ++++++------------- 3 files changed, 16 insertions(+), 27 deletions(-) diff --git a/src/web/client/common/constants.ts b/src/web/client/common/constants.ts index bc2d613b6..e6bdf2288 100644 --- a/src/web/client/common/constants.ts +++ b/src/web/client/common/constants.ts @@ -96,7 +96,6 @@ export enum queryParameters { ENV_ID = "envid", GEO = "geo", // User geo location ENABLE_MULTIFILE = "enablemultifile", - WEBSITE_PREVIEW_URL = "websitepreviewurl", ENTITY = "entity", ENTITY_ID = "entityid", REFERRER_SOURCE = "referrersource", diff --git a/src/web/client/utilities/commonUtil.ts b/src/web/client/utilities/commonUtil.ts index b859f8450..59d79b3fa 100644 --- a/src/web/client/utilities/commonUtil.ts +++ b/src/web/client/utilities/commonUtil.ts @@ -310,7 +310,7 @@ export function getRangeForMultilineMatch(text: string, pattern: string, index: return range; } -export async function validateWebsitePreviewURL(): Promise { +export async function validateWebsitePreviewURL(): Promise<{ websiteUrl: string, isValid: boolean }> { const envId = getEnvironmentIdFromUrl(); const serviceEndpointStamp = WebExtensionContext.serviceEndpointCategory; const websitePreviewId = WebExtensionContext.urlParametersMap?.get(queryParameters.PORTAL_ID); @@ -321,7 +321,7 @@ export async function validateWebsitePreviewURL(): Promise { validateWebsitePreviewURL.name, `serviceEndpointStamp:${serviceEndpointStamp}, envId:${envId}, websitePreviewId:${websitePreviewId}` ); - return false; + return { websiteUrl: '', isValid: false }; } const siteDetails = await PPAPIService.getWebsiteDetailsById(serviceEndpointStamp, envId, websitePreviewId, WebExtensionContext.telemetry.getTelemetryReporter()); @@ -331,11 +331,12 @@ export async function validateWebsitePreviewURL(): Promise { webExtensionTelemetryEventNames.WEB_EXTENSION_WEBSITE_PREVIEW_URL_VALIDATION_SITE_DETAILS_FETCH_FAILED, validateWebsitePreviewURL.name, ); - return false; + return { websiteUrl: '', isValid: false }; } - return siteDetails.websiteUrl.length !== 0 && - WebExtensionContext.urlParametersMap.get(queryParameters.WEBSITE_PREVIEW_URL) !== undefined && - siteDetails.websiteUrl.toLocaleLowerCase().trim() === WebExtensionContext.urlParametersMap.get(queryParameters.WEBSITE_PREVIEW_URL)?.toLocaleLowerCase().trim(); -} + if (siteDetails.websiteUrl.length !== 0) { + return { websiteUrl: siteDetails.websiteUrl, isValid: true }; + } + return { websiteUrl: '', isValid: false }; +} diff --git a/src/web/client/webViews/powerPagesNavigationProvider.ts b/src/web/client/webViews/powerPagesNavigationProvider.ts index 93e0b1567..581186f6d 100644 --- a/src/web/client/webViews/powerPagesNavigationProvider.ts +++ b/src/web/client/webViews/powerPagesNavigationProvider.ts @@ -6,15 +6,15 @@ import * as vscode from 'vscode'; import * as path from 'path'; import WebExtensionContext from "../WebExtensionContext"; -import { httpMethod, queryParameters } from '../common/constants'; -import { getBackToStudioURL, isStringUndefinedOrEmpty, validateWebsitePreviewURL } from '../utilities/commonUtil'; +import { httpMethod } from '../common/constants'; +import { getBackToStudioURL, validateWebsitePreviewURL } from '../utilities/commonUtil'; import { webExtensionTelemetryEventNames } from '../../../common/OneDSLoggerTelemetry/web/client/webExtensionTelemetryEvents'; export class PowerPagesNavigationProvider implements vscode.TreeDataProvider { private _onDidChangeTreeData: vscode.EventEmitter = new vscode.EventEmitter(); readonly onDidChangeTreeData: vscode.Event = this._onDidChangeTreeData.event; - private isWebsitePreviewURLValid: Promise = validateWebsitePreviewURL(); + private isWebsitePreviewURLValid: Promise<{ websiteUrl: string, isValid: boolean }> = validateWebsitePreviewURL(); refresh(): void { this._onDidChangeTreeData.fire(); @@ -63,33 +63,22 @@ export class PowerPagesNavigationProvider implements vscode.TreeDataProvider { let requestSentAtTime = new Date().getTime(); - const websitePreviewUrl = WebExtensionContext.urlParametersMap.get(queryParameters.WEBSITE_PREVIEW_URL) as string; - if (isStringUndefinedOrEmpty(websitePreviewUrl)) { - vscode.window.showErrorMessage(vscode.l10n.t("Preview site URL is not available")); + const validationResult = await this.isWebsitePreviewURLValid; - WebExtensionContext.telemetry.sendErrorTelemetry( - webExtensionTelemetryEventNames.WEB_EXTENSION_WEBSITE_PREVIEW_URL_UNAVAILABLE, - this.previewPowerPageSite.name, - `websitePreviewUrl:${websitePreviewUrl}` - ); - return; - } - - const isValid = await this.isWebsitePreviewURLValid; - if (!isValid) { + if (!validationResult.isValid) { vscode.window.showErrorMessage(vscode.l10n.t("Preview site URL is not valid")); WebExtensionContext.telemetry.sendErrorTelemetry( webExtensionTelemetryEventNames.WEB_EXTENSION_WEBSITE_PREVIEW_URL_INVALID, this.previewPowerPageSite.name, - `websitePreviewUrl:${websitePreviewUrl}` + `websitePreviewUrl:${validationResult.websiteUrl}` ); return; } // Runtime clear cache call - const requestUrl = `${websitePreviewUrl.endsWith('/') ? websitePreviewUrl : websitePreviewUrl.concat('/')}_services/cache/config`; + const requestUrl = `${validationResult.websiteUrl.endsWith('/') ? validationResult.websiteUrl : validationResult.websiteUrl.concat('/')}_services/cache/config`; WebExtensionContext.telemetry.sendAPITelemetry( requestUrl, @@ -141,7 +130,7 @@ export class PowerPagesNavigationProvider implements vscode.TreeDataProvider Date: Tue, 21 Jan 2025 20:00:06 +0530 Subject: [PATCH 2/4] Translations --- l10n/bundle.l10n.json | 1 - .../vscode-powerplatform.xlf | 31 +++++++++---------- 2 files changed, 14 insertions(+), 18 deletions(-) diff --git a/l10n/bundle.l10n.json b/l10n/bundle.l10n.json index c27052a9f..4cdfcb223 100644 --- a/l10n/bundle.l10n.json +++ b/l10n/bundle.l10n.json @@ -7,7 +7,6 @@ "You are editing a live, public site ": "You are editing a live, public site ", "Preview site": "Preview site", "Open in Power Pages studio": "Open in Power Pages studio", - "Preview site URL is not available": "Preview site URL is not available", "Preview site URL is not valid": "Preview site URL is not valid", "Opening preview site...": "Opening preview site...", "Power Pages studio URL is not available": "Power Pages studio URL is not available", diff --git a/loc/translations-export/vscode-powerplatform.xlf b/loc/translations-export/vscode-powerplatform.xlf index 4ce3e7f1a..87233ec87 100644 --- a/loc/translations-export/vscode-powerplatform.xlf +++ b/loc/translations-export/vscode-powerplatform.xlf @@ -386,9 +386,6 @@ The {3} represents Dataverse Environment's Organization ID (GUID) Preview site - - Preview site URL is not available - Preview site URL is not valid @@ -548,8 +545,8 @@ The {3} represents Dataverse Environment's Organization ID (GUID) Auth Profiles - Avoid accidental overwrites when you try to save outdated code in VS Code for the Web. You can compare the changes side-by-side and decide to accept or revert the changes. - + Avoid accidental overwrites when you try to save outdated code in VS Code for the Web. You can compare the changes side-by-side and decide to accept or revert the changes. + To learn more, visit [Prevent accidental overwrites](command:powerplatform-walkthrough.saveConflict-learn-more). 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 @@ -612,12 +609,12 @@ The fifth line should be '[TRANSLATION HERE](command:powerplatform-walkthrough.s File explorer - Find your page files organized in folders under your site name. All your pages are arranged into HTML, CSS, and JS files within the respective site component folders. - - You can find site components like forms, content snippets, lists, and more to edit. - - To learn more, visit [Power Pages file structure in VS Code](command:powerplatform-walkthrough.fileSystem-documentation). - + Find your page files organized in folders under your site name. All your pages are arranged into HTML, CSS, and JS files within the respective site component folders. + + You can find site components like forms, content snippets, lists, and more to edit. + + To learn more, visit [Power Pages file structure in VS Code](command:powerplatform-walkthrough.fileSystem-documentation). + [Visit site folder](command:powerplatform-walkthrough.fileSystem-open-folder) 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 @@ -651,7 +648,7 @@ The second line should be '[TRANSLATION HERE](command:pacCLI.authPanel.newAuthPr Now easily edit code of your Power Pages site. Access code from supported site components like forms, content snippets, lists, and more from within Visual Studio Code. - + To learn more, visit [Edit Power Pages code in VS Code](command:powerplatform-walkthrough.overview-learn-more). 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 @@ -710,11 +707,11 @@ The second line should be '[TRANSLATION HERE](command:powerplatform-walkthrough. Visual Studio Code for Web enables editing and publishing of web pages on your website. - - For a command line interface and more advanced capabilities, install the Power Platform Extension for VS Code, available in the VS Code Marketplace for desktop. - + + For a command line interface and more advanced capabilities, install the Power Platform Extension for VS Code, available in the VS Code Marketplace for desktop. + [Learn More](command:powerplatform-walkthrough.advancedCapabilities-learn-more) about the difference between Visual Studio Code for desktop and web. - + [Start coding](command:powerplatform-walkthrough.advancedCapabilities-start-coding) 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 @@ -724,4 +721,4 @@ The seventh line should be '[TRANSLATION HERE](command:powerplatform-walkthrough Which Azure Cloud Power Platform Tools should use for authentication. - + \ No newline at end of file From cc6faeaa01dd60824a22837d4b9eb3661329944d Mon Sep 17 00:00:00 2001 From: Priyanshu Agrawal Date: Tue, 21 Jan 2025 20:13:02 +0530 Subject: [PATCH 3/4] Deconstruct object --- .../client/webViews/powerPagesNavigationProvider.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/web/client/webViews/powerPagesNavigationProvider.ts b/src/web/client/webViews/powerPagesNavigationProvider.ts index 581186f6d..b65225559 100644 --- a/src/web/client/webViews/powerPagesNavigationProvider.ts +++ b/src/web/client/webViews/powerPagesNavigationProvider.ts @@ -64,21 +64,21 @@ export class PowerPagesNavigationProvider implements vscode.TreeDataProvider { let requestSentAtTime = new Date().getTime(); - const validationResult = await this.isWebsitePreviewURLValid; + const { isValid, websiteUrl } = await this.isWebsitePreviewURLValid; - if (!validationResult.isValid) { + if (!isValid) { vscode.window.showErrorMessage(vscode.l10n.t("Preview site URL is not valid")); WebExtensionContext.telemetry.sendErrorTelemetry( webExtensionTelemetryEventNames.WEB_EXTENSION_WEBSITE_PREVIEW_URL_INVALID, this.previewPowerPageSite.name, - `websitePreviewUrl:${validationResult.websiteUrl}` + `websitePreviewUrl:${websiteUrl}` ); return; } // Runtime clear cache call - const requestUrl = `${validationResult.websiteUrl.endsWith('/') ? validationResult.websiteUrl : validationResult.websiteUrl.concat('/')}_services/cache/config`; + const requestUrl = `${websiteUrl.endsWith('/') ? websiteUrl : websiteUrl.concat('/')}_services/cache/config`; WebExtensionContext.telemetry.sendAPITelemetry( requestUrl, @@ -130,7 +130,7 @@ export class PowerPagesNavigationProvider implements vscode.TreeDataProvider Date: Wed, 22 Jan 2025 14:04:09 +0530 Subject: [PATCH 4/4] Rename method --- src/web/client/utilities/commonUtil.ts | 8 ++++---- src/web/client/webViews/powerPagesNavigationProvider.ts | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/web/client/utilities/commonUtil.ts b/src/web/client/utilities/commonUtil.ts index 59d79b3fa..9f393829d 100644 --- a/src/web/client/utilities/commonUtil.ts +++ b/src/web/client/utilities/commonUtil.ts @@ -54,7 +54,7 @@ export function GetFileNameWithExtension( } export function isLanguageCodeNeededInFileName(entity: string) { - return entity === schemaEntityName.WEBPAGES ||entity === schemaEntityName.CONTENTSNIPPETS; + return entity === schemaEntityName.WEBPAGES || entity === schemaEntityName.CONTENTSNIPPETS; } export function isExtensionNeededInFileName(entity: string) { @@ -310,7 +310,7 @@ export function getRangeForMultilineMatch(text: string, pattern: string, index: return range; } -export async function validateWebsitePreviewURL(): Promise<{ websiteUrl: string, isValid: boolean }> { +export async function getValidWebsitePreviewUrl(): Promise<{ websiteUrl: string, isValid: boolean }> { const envId = getEnvironmentIdFromUrl(); const serviceEndpointStamp = WebExtensionContext.serviceEndpointCategory; const websitePreviewId = WebExtensionContext.urlParametersMap?.get(queryParameters.PORTAL_ID); @@ -318,7 +318,7 @@ export async function validateWebsitePreviewURL(): Promise<{ websiteUrl: string, if (serviceEndpointStamp === ServiceEndpointCategory.NONE || !envId || !websitePreviewId) { WebExtensionContext.telemetry.sendErrorTelemetry( webExtensionTelemetryEventNames.WEB_EXTENSION_WEBSITE_PREVIEW_URL_VALIDATION_INSUFFICIENT_PARAMETERS, - validateWebsitePreviewURL.name, + getValidWebsitePreviewUrl.name, `serviceEndpointStamp:${serviceEndpointStamp}, envId:${envId}, websitePreviewId:${websitePreviewId}` ); return { websiteUrl: '', isValid: false }; @@ -329,7 +329,7 @@ export async function validateWebsitePreviewURL(): Promise<{ websiteUrl: string, if (siteDetails == null) { WebExtensionContext.telemetry.sendErrorTelemetry( webExtensionTelemetryEventNames.WEB_EXTENSION_WEBSITE_PREVIEW_URL_VALIDATION_SITE_DETAILS_FETCH_FAILED, - validateWebsitePreviewURL.name, + getValidWebsitePreviewUrl.name, ); return { websiteUrl: '', isValid: false }; } diff --git a/src/web/client/webViews/powerPagesNavigationProvider.ts b/src/web/client/webViews/powerPagesNavigationProvider.ts index b65225559..8d1d112d3 100644 --- a/src/web/client/webViews/powerPagesNavigationProvider.ts +++ b/src/web/client/webViews/powerPagesNavigationProvider.ts @@ -7,14 +7,14 @@ import * as vscode from 'vscode'; import * as path from 'path'; import WebExtensionContext from "../WebExtensionContext"; import { httpMethod } from '../common/constants'; -import { getBackToStudioURL, validateWebsitePreviewURL } from '../utilities/commonUtil'; +import { getBackToStudioURL, getValidWebsitePreviewUrl } from '../utilities/commonUtil'; import { webExtensionTelemetryEventNames } from '../../../common/OneDSLoggerTelemetry/web/client/webExtensionTelemetryEvents'; export class PowerPagesNavigationProvider implements vscode.TreeDataProvider { private _onDidChangeTreeData: vscode.EventEmitter = new vscode.EventEmitter(); readonly onDidChangeTreeData: vscode.Event = this._onDidChangeTreeData.event; - private isWebsitePreviewURLValid: Promise<{ websiteUrl: string, isValid: boolean }> = validateWebsitePreviewURL(); + private isWebsitePreviewURLValid: Promise<{ websiteUrl: string, isValid: boolean }> = getValidWebsitePreviewUrl(); refresh(): void { this._onDidChangeTreeData.fire();