diff --git a/loc/translations-export/vscode-powerplatform.xlf b/loc/translations-export/vscode-powerplatform.xlf index 6c689160..30be59fd 100644 --- a/loc/translations-export/vscode-powerplatform.xlf +++ b/loc/translations-export/vscode-powerplatform.xlf @@ -257,17 +257,6 @@ The {2} represents Solution's Version number Unable to find that app - - - There was a problem opening the workspace - - - Try refreshing the browser - - - Authorization Failed. Please run again to authorize it - - There was a problem opening the workspace @@ -282,24 +271,12 @@ The {2} represents Solution's Version number Check the URL and verify the parameters are correct - - - There’s a problem on the back end + + + Fetching your file ... - - Try again - - - Authorization Failed. Please run again to authorize it - - - There was a permissions problem with the server - - - One or more commands are invalid or malformed - - - Check the parameters and try again + + Saving your file ... diff --git a/src/web/client/common/authenticationProvider.ts b/src/web/client/common/authenticationProvider.ts index 6b167fb0..5c766b6a 100644 --- a/src/web/client/common/authenticationProvider.ts +++ b/src/web/client/common/authenticationProvider.ts @@ -6,10 +6,8 @@ import * as vscode from 'vscode'; import * as nls from 'vscode-nls'; nls.config({ messageFormat: nls.MessageFormat.bundle, bundleFormat: nls.BundleFormat.standalone })(); -const localize: nls.LocalizeFunc = nls.loadMessageBundle(); import { sendErrorTelemetry } from '../telemetry/webExtensionTelemetry'; import { pathParamToSchema, PROVIDER_ID, telemetryEventNames } from './constants'; -import { showErrorDialog } from './errorHandler'; import PowerPlatformExtensionContextManager from "./localStore"; export function getHeader(accessToken: string) { @@ -30,13 +28,10 @@ export async function dataverseAuthentication(dataverseOrgURL: string): Promise< if (!accessToken) { { - showErrorDialog(localize("microsoft-powerapps-portals.webExtension.init.error", "There was a problem opening the workspace"), localize("microsoft-powerapps-portals.webExtension.init.error.desc", "Try refreshing the browser")); sendErrorTelemetry(telemetryEventNames.WEB_EXTENSION_NO_ACCESS_TOKEN); - return ''; } } } catch (error) { - vscode.window.showErrorMessage(localize("microsoft-powerapps-portals.webExtension.init.authorization.error", "Authorization Failed. Please run again to authorize it")); const authError = (error as Error)?.message; sendErrorTelemetry(telemetryEventNames.WEB_EXTENSION_DATAVERSE_AUTHENTICATION_FAILED, authError); } diff --git a/src/web/client/common/constants.ts b/src/web/client/common/constants.ts index 209059c8..4964d267 100644 --- a/src/web/client/common/constants.ts +++ b/src/web/client/common/constants.ts @@ -119,7 +119,8 @@ export enum queryParameters { SCHEMA = 'schema', DATA_SOURCE = 'dataSource', REFERRER_SESSION_ID = 'referrerSessionId', - REFERRER = 'referrer' + REFERRER = 'referrer', + SITE_VISIBILITY = 'siteVisibility' } export enum telemetryEventNames { @@ -134,4 +135,6 @@ export enum telemetryEventNames { WEB_EXTENSION_API_REQUEST_SUCCESS = 'WebExtensionApiRequestSuccess', WEB_EXTENSION_EMPTY_FILE_NAME = 'WebExtensionEmptyFileName', WEB_EXTENSION_SET_CONTEXT_PERF = 'WebExtensionSetContextPerf', + WEB_EXTENSION_EDIT_LCID = 'WebExtensionEditLcid', + WEB_EXTENSION_EDIT_LANGUAGE_CODE = 'WebExtensionEditLanguageCode', } diff --git a/src/web/client/common/fileSystemProvider.ts b/src/web/client/common/fileSystemProvider.ts index db211fb6..9e4af5f4 100644 --- a/src/web/client/common/fileSystemProvider.ts +++ b/src/web/client/common/fileSystemProvider.ts @@ -13,6 +13,9 @@ import PowerPlatformExtensionContextManager from "./localStore"; import { SaveEntityDetails } from './portalSchemaInterface'; import { fetchDataFromDataverseAndUpdateVFS } from './remoteFetchProvider'; import { saveData } from './remoteSaveProvider'; +import * as nls from 'vscode-nls'; +nls.config({ messageFormat: nls.MessageFormat.bundle, bundleFormat: nls.BundleFormat.standalone })(); +const localize: nls.LocalizeFunc = nls.loadMessageBundle(); export class File implements vscode.FileStat { @@ -79,7 +82,13 @@ export class PortalsFS implements vscode.FileSystemProvider { if (castedError.code === vscode.FileSystemError.FileNotFound.name) { const powerPlatformContext = await PowerPlatformExtensionContextManager.getPowerPlatformExtensionContext(); if (powerPlatformContext.rootDirectory && uri.toString().toLowerCase() === powerPlatformContext.rootDirectory.toString().toLowerCase()) { - await this._loadFromDataverseToVFS(); + await vscode.window.withProgress({ + location: vscode.ProgressLocation.Notification, + cancellable: true, + title: localize("microsoft-powerapps-portals.webExtension.fetch.file.message", "Fetching your file ...") + }, async () => { + await this._loadFromDataverseToVFS(); + }); } } } @@ -101,10 +110,15 @@ export class PortalsFS implements vscode.FileSystemProvider { if (rootDirectory && uri.toString().includes(rootDirectory.toString())) { if (PathHasEntityFolderName(uri.toString())) { - await this._loadFromDataverseToVFS(); - - const data = await this._lookupAsFile(uri, false); - return data.data; + await vscode.window.withProgress({ + location: vscode.ProgressLocation.Notification, + cancellable: true, + title: localize("microsoft-powerapps-portals.webExtension.fetch.file.message", "Fetching your file ...") + }, async () => { + await this._loadFromDataverseToVFS(); + const data = await this._lookupAsFile(uri, false); + return data.data; + }); } } } @@ -131,7 +145,13 @@ export class PortalsFS implements vscode.FileSystemProvider { this._fireSoon({ type: vscode.FileChangeType.Created, uri }); } else if (PowerPlatformExtensionContextManager.getPowerPlatformExtensionContext().saveDataMap.has(uri.fsPath)) { // Save data to dataverse - await this._saveFileToDataverseFromVFS(uri, content); + await vscode.window.withProgress({ + location: vscode.ProgressLocation.Notification, + cancellable: true, + title: localize("microsoft-powerapps-portals.webExtension.save.file.message", "Saving your file ...") + }, async () => { + await this._saveFileToDataverseFromVFS(uri, content); + }); } entry.mtime = Date.now(); diff --git a/src/web/client/common/localStore.ts b/src/web/client/common/localStore.ts index c63ef420..4317f563 100644 --- a/src/web/client/common/localStore.ts +++ b/src/web/client/common/localStore.ts @@ -7,11 +7,8 @@ import * as vscode from "vscode"; import { dataverseAuthentication, getCustomRequestURL, getHeader } from "./authenticationProvider"; import { MULTI_ENTITY_URL_KEY, ORG_URL, pathParamToSchema, PORTALS_URI_SCHEME, PORTAL_LANGUAGES, PORTAL_LANGUAGE_DEFAULT, WEBSITES, WEBSITE_LANGUAGES, WEBSITE_NAME } from "./constants"; import { getDataSourcePropertiesMap, getEntitiesFolderNameMap, getEntitiesSchemaMap } from "./portalSchemaReader"; -import { showErrorDialog } from "./errorHandler"; -import * as nls from 'vscode-nls'; import { SaveEntityDetails } from "./portalSchemaInterface"; -nls.config({ messageFormat: nls.MessageFormat.bundle, bundleFormat: nls.BundleFormat.standalone })(); -const localize: nls.LocalizeFunc = nls.loadMessageBundle(); +import { sendAPIFailureTelemetry, sendAPISuccessTelemetry, sendAPITelemetry } from "../telemetry/webExtensionTelemetry"; export interface IPowerPlatformExtensionContext { dataSourcePropertiesMap: Map; // dataSourceProperties in portal_schema_data @@ -70,13 +67,15 @@ class PowerPlatformExtensionContextManager { const dataverseOrgUrl = this.PowerPlatformExtensionContext.queryParamsMap.get(ORG_URL) as string; const accessToken: string = await dataverseAuthentication(dataverseOrgUrl); - this.PowerPlatformExtensionContext = { - ... this.PowerPlatformExtensionContext, - websiteIdToLanguage: await this.websiteIdToLanguageMap(accessToken, dataverseOrgUrl), - websiteLanguageIdToPortalLanguageMap: await this.websiteLanguageIdToPortalLanguage(accessToken, dataverseOrgUrl), - languageIdCodeMap: await this.languageIdToCode(accessToken, dataverseOrgUrl), - dataverseAccessToken: accessToken, - }; + if (accessToken) { + this.PowerPlatformExtensionContext = { + ... this.PowerPlatformExtensionContext, + websiteIdToLanguage: await this.websiteIdToLanguageMap(accessToken, dataverseOrgUrl), + websiteLanguageIdToPortalLanguageMap: await this.websiteLanguageIdToPortalLanguage(accessToken, dataverseOrgUrl), + languageIdCodeMap: await this.languageIdToCode(accessToken, dataverseOrgUrl), + dataverseAccessToken: accessToken, + }; + } return this.PowerPlatformExtensionContext; } @@ -100,16 +99,22 @@ class PowerPlatformExtensionContextManager { } private async languageIdToCode(accessToken: string, dataverseOrgUrl: string): Promise> { + let requestUrl = ''; + let requestSentAtTime = new Date().getTime(); const languageIdCodeMap = new Map(); try { - const requestUrl = getCustomRequestURL(dataverseOrgUrl, PORTAL_LANGUAGES, MULTI_ENTITY_URL_KEY); + requestUrl = getCustomRequestURL(dataverseOrgUrl, PORTAL_LANGUAGES, MULTI_ENTITY_URL_KEY); + sendAPITelemetry(requestUrl); + + requestSentAtTime = new Date().getTime(); const response = await fetch(requestUrl, { headers: getHeader(accessToken), }); - if (!response.ok) { - showErrorDialog(localize("microsoft-powerapps-portals.webExtension.backend.error", "There’s a problem on the back end"), localize("microsoft-powerapps-portals.webExtension.backend.desc", "Try again")); + if (!response?.ok) { + sendAPIFailureTelemetry(requestUrl, new Date().getTime() - requestSentAtTime, response?.statusText); } - const result = await response.json(); + sendAPISuccessTelemetry(requestUrl, new Date().getTime() - requestSentAtTime); + const result = await response?.json(); if (result) { if (result.value?.length > 0) { for (let counter = 0; counter < result.value.length; counter++) { @@ -120,27 +125,29 @@ class PowerPlatformExtensionContextManager { } } } catch (error) { - if (typeof error === "string" && error.includes("Unauthorized")) { - showErrorDialog(localize("microsoft-powerapps-portals.webExtension.unauthorized.error", "Authorization Failed. Please run again to authorize it"), localize("microsoft-powerapps-portals.webExtension.unauthorized.desc", "There was a permissions problem with the server")); - } - else { - showErrorDialog(localize("microsoft-powerapps-portals.webExtension.parameter.error", "One or more commands are invalid or malformed"), localize("microsoft-powerapps-portals.webExtension.parameter.desc", "Check the parameters and try again")); - } + const errorMsg = (error as Error)?.message; + sendAPIFailureTelemetry(requestUrl, new Date().getTime() - requestSentAtTime, errorMsg); } return languageIdCodeMap; } private async websiteLanguageIdToPortalLanguage(accessToken: string, dataverseOrgUrl: string): Promise> { + let requestUrl = ''; + let requestSentAtTime = new Date().getTime(); const websiteLanguageIdToPortalLanguageMap = new Map(); try { - const requestUrl = getCustomRequestURL(dataverseOrgUrl, WEBSITE_LANGUAGES, MULTI_ENTITY_URL_KEY); + requestUrl = getCustomRequestURL(dataverseOrgUrl, WEBSITE_LANGUAGES, MULTI_ENTITY_URL_KEY); + sendAPITelemetry(requestUrl); + + requestSentAtTime = new Date().getTime(); const response = await fetch(requestUrl, { headers: getHeader(accessToken), }); - if (!response.ok) { - showErrorDialog(localize("microsoft-powerapps-portals.webExtension.backend.error", "One or more commands are invalid or malformed"), localize("microsoft-powerapps-portals.webExtension.backend.desc", "Check the parameters and try again")); + if (!response?.ok) { + sendAPIFailureTelemetry(requestUrl, new Date().getTime() - requestSentAtTime, response?.statusText); } - const result = await response.json(); + sendAPISuccessTelemetry(requestUrl, new Date().getTime() - requestSentAtTime); + const result = await response?.json(); if (result) { if (result.value?.length > 0) { for (let counter = 0; counter < result.value.length; counter++) { @@ -151,28 +158,30 @@ class PowerPlatformExtensionContextManager { } } } catch (error) { - if (typeof error === "string" && error.includes("Unauthorized")) { - showErrorDialog(localize("microsoft-powerapps-portals.webExtension.unauthorized.error", "Authorization Failed. Please run again to authorize it"), localize("microsoft-powerapps-portals.webExtension.unauthorized.desc", "There was a permissions problem with the server")); - } - else { - showErrorDialog(localize("microsoft-powerapps-portals.webExtension.parameter.error", "One or more commands are invalid or malformed"), localize("microsoft-powerapps-portals.webExtension.parameter.desc", "Check the parameters and try again")); - } + const errorMsg = (error as Error)?.message; + sendAPIFailureTelemetry(requestUrl, new Date().getTime() - requestSentAtTime, errorMsg); } return websiteLanguageIdToPortalLanguageMap; } private async websiteIdToLanguageMap(accessToken: string, dataverseOrgUrl: string): Promise> { + let requestUrl = ''; + let requestSentAtTime = new Date().getTime(); const websiteIdToLanguage = new Map(); try { - const requestUrl = getCustomRequestURL(dataverseOrgUrl, WEBSITES, MULTI_ENTITY_URL_KEY); + requestUrl = getCustomRequestURL(dataverseOrgUrl, WEBSITES, MULTI_ENTITY_URL_KEY); + sendAPITelemetry(requestUrl); + + requestSentAtTime = new Date().getTime(); const response = await fetch(requestUrl, { headers: getHeader(accessToken), }); - if (!response.ok) { - showErrorDialog(localize("microsoft-powerapps-portals.webExtension.backend.error", "One or more commands are invalid or malformed"), localize("microsoft-powerapps-portals.webExtension.backend.desc", "Check the parameters and try again")); + if (!response?.ok) { + sendAPIFailureTelemetry(requestUrl, new Date().getTime() - requestSentAtTime, response?.statusText); } - const result = await response.json(); + sendAPISuccessTelemetry(requestUrl, new Date().getTime() - requestSentAtTime); + const result = await response?.json(); if (result) { if (result.value?.length > 0) { @@ -185,12 +194,8 @@ class PowerPlatformExtensionContextManager { } } catch (error) { - if (typeof error === "string" && error.includes("Unauthorized")) { - showErrorDialog(localize("microsoft-powerapps-portals.webExtension.unauthorized.error", "Authorization Failed. Please run again to authorize it"), localize("microsoft-powerapps-portals.webExtension.unauthorized.desc", "There was a permissions problem with the server")); - } - else { - showErrorDialog(localize("microsoft-powerapps-portals.webExtension.parameter.error", "One or more commands are invalid or malformed"), localize("microsoft-powerapps-portals.webExtension.parameter.desc", "Check the parameters and try again")); - } + const errorMsg = (error as Error)?.message; + sendAPIFailureTelemetry(requestUrl, new Date().getTime() - requestSentAtTime, errorMsg); } return websiteIdToLanguage; } diff --git a/src/web/client/common/remoteFetchProvider.ts b/src/web/client/common/remoteFetchProvider.ts index 6d678fa4..c5ec9048 100644 --- a/src/web/client/common/remoteFetchProvider.ts +++ b/src/web/client/common/remoteFetchProvider.ts @@ -11,7 +11,8 @@ import { sendAPIFailureTelemetry, sendAPISuccessTelemetry, sendAPITelemetry, - sendErrorTelemetry + sendErrorTelemetry, + sendInfoTelemetry } from '../telemetry/webExtensionTelemetry'; import { fromBase64, GetFileNameWithExtension, useBase64 } from '../utility/CommonUtility'; import { @@ -68,14 +69,14 @@ export async function fetchDataFromDataverseAndUpdateVFS( await createContentFiles(data[counter], entity, queryParamsMap, entitiesSchemaMap, languageIdCodeMap, portalFs, entityId, websiteIdToLanguage); } } catch (error) { - const authError = (error as Error)?.message; + const errorMsg = (error as Error)?.message; if (typeof error === "string" && error.includes("Unauthorized")) { showErrorDialog(localize("microsoft-powerapps-portals.webExtension.unauthorized.error", "Authorization Failed. Please run again to authorize it"), localize("microsoft-powerapps-portals.webExtension.unauthorized.desc", "There was a permissions problem with the server")); } else { showErrorDialog(localize("microsoft-powerapps-portals.webExtension.parameter.error", "One or more commands are invalid or malformed"), localize("microsoft-powerapps-portals.webExtension.parameter.desc", "Check the parameters and try again")); } - sendAPIFailureTelemetry(requestUrl, new Date().getTime() - requestSentAtTime, authError); + sendAPIFailureTelemetry(requestUrl, new Date().getTime() - requestSentAtTime, errorMsg); } } @@ -93,6 +94,7 @@ async function createContentFiles( const lcid: string | undefined = websiteIdToLanguage.get(queryParamsMap.get(Constants.WEBSITE_ID) as string) ? websiteIdToLanguage.get(queryParamsMap.get(Constants.WEBSITE_ID) as string) : Constants.DEFAULT_LANGUAGE_CODE; + sendInfoTelemetry(Constants.telemetryEventNames.WEB_EXTENSION_EDIT_LCID, { 'lcid': (lcid ? lcid.toString() : '') }); const entityEntry = entitiesSchemaMap.get(Constants.pathParamToSchema.get(entity) as string); const attributes = entityEntry?.get('_attributes'); const exportType = entityEntry?.get('_exporttype'); @@ -105,7 +107,7 @@ async function createContentFiles( ? languageIdCodeMap.get(lcid) as string : Constants.DEFAULT_LANGUAGE_CODE; } - + sendInfoTelemetry(Constants.telemetryEventNames.WEB_EXTENSION_EDIT_LANGUAGE_CODE, { 'languageCode': (languageCode ? languageCode.toString(): '') }); let filePathInPortalFS = ''; if (exportType && (exportType === Constants.exportType.SubFolders || exportType === Constants.exportType.SingleFolder)) { filePathInPortalFS = `${PORTALS_URI_SCHEME}:/${portalFolderName}/${subUri}/`; @@ -159,6 +161,7 @@ async function createContentFiles( // Not awaited intentionally vscode.commands.executeCommand('vscode.open', vscode.Uri.parse(fileUri), {background: true, preview: false}); + sendInfoTelemetry("StartCommand", { 'commandId': 'vscode.open', 'type': 'file' }); } } diff --git a/src/web/client/common/remoteSaveProvider.ts b/src/web/client/common/remoteSaveProvider.ts index ee5ad48d..f2593b66 100644 --- a/src/web/client/common/remoteSaveProvider.ts +++ b/src/web/client/common/remoteSaveProvider.ts @@ -4,7 +4,7 @@ */ import * as vscode from 'vscode'; -import { sendAPIFailureTelemetry, sendAPITelemetry } from '../telemetry/webExtensionTelemetry'; +import { sendAPIFailureTelemetry, sendAPISuccessTelemetry, sendAPITelemetry } from '../telemetry/webExtensionTelemetry'; import { getHeader } from './authenticationProvider'; import { BAD_REQUEST, MIMETYPE } from './constants'; import { showErrorDialog } from './errorHandler'; @@ -53,6 +53,8 @@ export async function saveData( showErrorDialog(localize("microsoft-powerapps-portals.webExtension.backend.error", "There’s a problem on the back end"), localize("microsoft-powerapps-portals.webExtension.retry.desc", "Try again")); throw new Error(response.statusText); } + + sendAPISuccessTelemetry(requestUrl, new Date().getTime() - requestSentAtTime); } catch (error) { const authError = (error as Error)?.message; diff --git a/src/web/client/extension.ts b/src/web/client/extension.ts index fd4d67fc..14a1b3d2 100644 --- a/src/web/client/extension.ts +++ b/src/web/client/extension.ts @@ -10,10 +10,10 @@ import * as vscode from "vscode"; import TelemetryReporter from "@vscode/extension-telemetry"; import { AI_KEY } from '../../common/telemetry/generated/telemetryConfiguration'; import PowerPlatformExtensionContextManager from "./common/localStore"; -import { PORTALS_URI_SCHEME, telemetryEventNames, SITE_VISIBILITY, PUBLIC, IS_FIRST_RUN_EXPERIENCE } from "./common/constants"; +import { PORTALS_URI_SCHEME, SITE_VISIBILITY, PUBLIC, IS_FIRST_RUN_EXPERIENCE } from "./common/constants"; import { PortalsFS } from "./common/fileSystemProvider"; import { checkMandatoryParameters, removeEncodingFromParameters, ERRORS } from "./common/errorHandler"; -import { sendExtensionInitPathParametersTelemetry, sendExtensionInitQueryParametersTelemetry, sendPerfTelemetry, setTelemetryReporter } from "./telemetry/webExtensionTelemetry"; +import { sendExtensionInitPathParametersTelemetry, sendExtensionInitQueryParametersTelemetry, sendInfoTelemetry, setTelemetryReporter } from "./telemetry/webExtensionTelemetry"; let _telemetry: TelemetryReporter; const localize: nls.LocalizeFunc = nls.loadMessageBundle(); @@ -23,8 +23,8 @@ export function activate(context: vscode.ExtensionContext): void { context.subscriptions.push(_telemetry); setTelemetryReporter(_telemetry); - _telemetry.sendTelemetryEvent("Start"); - _telemetry.sendTelemetryEvent("activated"); + sendInfoTelemetry("Start"); + sendInfoTelemetry("activated"); const portalsFS = new PortalsFS(); context.subscriptions.push(vscode.workspace.registerFileSystemProvider(PORTALS_URI_SCHEME, portalsFS, { isCaseSensitive: true })); @@ -32,7 +32,7 @@ export function activate(context: vscode.ExtensionContext): void { vscode.commands.registerCommand( "microsoft-powerapps-portals.webExtension.init", async (args) => { - _telemetry.sendTelemetryEvent("StartCommand", { 'commandId': 'microsoft-powerapps-portals.webExtension.init' }); + sendInfoTelemetry("StartCommand", { 'commandId': 'microsoft-powerapps-portals.webExtension.init' }); const { appName, entity, entityId, searchParams } = args; const queryParamsMap = new Map(); @@ -62,18 +62,15 @@ export function activate(context: vscode.ExtensionContext): void { switch (appName) { case 'portal': { sendExtensionInitQueryParametersTelemetry(searchParams); - + const isFirstRun = context.globalState.get(IS_FIRST_RUN_EXPERIENCE, true); if (isFirstRun) { vscode.commands.executeCommand(`workbench.action.openWalkthrough`,`microsoft-IsvExpTools.powerplatform-vscode#PowerPage-gettingStarted`, false); context.globalState.update(IS_FIRST_RUN_EXPERIENCE, false); + sendInfoTelemetry("StartCommand", { 'commandId': 'workbench.action.openWalkthrough', 'walkthroughId': 'microsoft-IsvExpTools.powerplatform-vscode#PowerPage-gettingStarted' }); } - + await vscode.workspace.fs.readDirectory(PowerPlatformExtensionContextManager.getPowerPlatformExtensionContext().rootDirectory); - - const timeStampBeforeSettingContext = new Date().getTime(); - const timeTakenToSetContext = new Date().getTime() - timeStampBeforeSettingContext; - sendPerfTelemetry(telemetryEventNames.WEB_EXTENSION_SET_CONTEXT_PERF, timeTakenToSetContext); } break; case 'default': @@ -88,29 +85,34 @@ export function activate(context: vscode.ExtensionContext): void { ) ); context.subscriptions.push(vscode.commands.registerCommand('powerplatform-walkthrough.overview-learn-more', async () => { + sendInfoTelemetry("StartCommand", { 'commandId': 'powerplatform-walkthrough.overview-learn-more' }); vscode.env.openExternal(vscode.Uri.parse("https://go.microsoft.com/fwlink/?linkid=2207914")); })); context.subscriptions.push(vscode.commands.registerCommand('powerplatform-walkthrough.fileSystem-documentation', async () => { + sendInfoTelemetry("StartCommand", { 'commandId': 'powerplatform-walkthrough.fileSystem-documentation' }); vscode.env.openExternal(vscode.Uri.parse("https://go.microsoft.com/fwlink/?linkid=2206616")); })); context.subscriptions.push(vscode.commands.registerCommand('powerplatform-walkthrough.fileSystem-open-folder', async () => { + sendInfoTelemetry("StartCommand", { 'commandId': 'powerplatform-walkthrough.fileSystem-open-folder' }); vscode.commands.executeCommand("workbench.view.explorer"); })); context.subscriptions.push(vscode.commands.registerCommand('powerplatform-walkthrough.advancedCapabilities-learn-more', async () => { + sendInfoTelemetry("StartCommand", { 'commandId': 'powerplatform-walkthrough.advancedCapabilities-learn-more' }); vscode.env.openExternal(vscode.Uri.parse("https://go.microsoft.com/fwlink/?linkid=2206366")); })); context.subscriptions.push(vscode.commands.registerCommand('powerplatform-walkthrough.advancedCapabilities-start-coding', async () => { + sendInfoTelemetry("StartCommand", { 'commandId': 'powerplatform-walkthrough.advancedCapabilities-start-coding' }); vscode.window.showTextDocument(PowerPlatformExtensionContextManager.getPowerPlatformExtensionContext().defaultFileUri); })); } export async function deactivate(): Promise { if (_telemetry) { - _telemetry.sendTelemetryEvent("End"); + sendInfoTelemetry("End"); _telemetry.dispose(); } } diff --git a/src/web/client/telemetry/webExtensionTelemetry.ts b/src/web/client/telemetry/webExtensionTelemetry.ts index ee779226..07eca9ae 100644 --- a/src/web/client/telemetry/webExtensionTelemetry.ts +++ b/src/web/client/telemetry/webExtensionTelemetry.ts @@ -19,6 +19,7 @@ export interface IPortalWebExtensionInitQueryParametersTelemetryData extends IWe 'schema'?: string; 'referrerSessionId'?: string; 'referrer'?: string; + 'siteVisibility'?: string; } } @@ -81,7 +82,8 @@ export function sendExtensionInitQueryParametersTelemetry(searchParams: URLSearc dataSource: getQueryParameterValue(queryParameters.DATA_SOURCE, searchParams), schema: getQueryParameterValue(queryParameters.SCHEMA, searchParams), referrerSessionId: getQueryParameterValue(queryParameters.REFERRER_SESSION_ID, searchParams), - referrer: getQueryParameterValue(queryParameters.REFERRER, searchParams) + referrer: getQueryParameterValue(queryParameters.REFERRER, searchParams), + siteVisibility: getQueryParameterValue(queryParameters.SITE_VISIBILITY, searchParams), } } _telemetry?.sendTelemetryEvent(telemetryData.eventName, telemetryData.properties); @@ -112,6 +114,14 @@ export function sendErrorTelemetry(eventName: string, errorMessage?: string) { } } +export function sendInfoTelemetry(eventName: string, properties?: Record) { + if (properties) { + _telemetry?.sendTelemetryEvent(eventName, properties); + } else { + _telemetry?.sendTelemetryEvent(eventName); + } +} + export function sendAPITelemetry(URL: string, isSuccessful?: boolean, duration?: number, errorMessage?: string, eventName?: string) { const telemetryData: IWebExtensionAPITelemetryData = { eventName: eventName ? eventName : telemetryEventNames.WEB_EXTENSION_API_REQUEST,