From 4bd8dd24f5ddfb5df03d01fc6b5a9bb9c08801fd Mon Sep 17 00:00:00 2001 From: amitjoshi Date: Fri, 12 Jul 2024 17:50:14 +0530 Subject: [PATCH] chore: Update PowerPagesCopilot.ts to include sample request in GitHub Copilot chat --- l10n/bundle.l10n.json | 10 +- .../vscode-powerplatform.xlf | 58 ++++--- package.json | 3 +- .../powerpages/PowerPagesChatParticipant.ts | 42 +++-- .../PowerPagesChatParticipantConstants.ts | 9 +- .../PowerPagesChatParticipantUtils.ts | 17 +- src/common/copilot/PowerPagesCopilot.ts | 2 +- .../CopilotNotificationPanel.ts | 159 ++++++++++-------- 8 files changed, 184 insertions(+), 116 deletions(-) diff --git a/l10n/bundle.l10n.json b/l10n/bundle.l10n.json index db78b8d0..8dcaf057 100644 --- a/l10n/bundle.l10n.json +++ b/l10n/bundle.l10n.json @@ -61,9 +61,11 @@ "Copied to clipboard!": "Copied to clipboard!", "What do you need help with?": "What do you need help with?", "Make sure AI-generated content is accurate and appropriate before using. Learn more | View\n terms": "Make sure AI-generated content is accurate and appropriate before using. Learn more | View\n terms", + "Try @powerpages with GitHub Copilot": "Try @powerpages with GitHub Copilot", + "Get GitHub Copilot to try @powerpages": "Get GitHub Copilot to try @powerpages", "Let Copilot help you code": "Let Copilot help you code", "Whether it’s HTML, CSS, JS, or Liquid code, just describe what you need and let AI build it for you. ": "Whether it’s HTML, CSS, JS, or Liquid code, just describe what you need and let AI build it for you. ", - "Try Copilot for Power Pages": "Try Copilot for Power Pages", + "Continue with Copilot for Power Pages": "Continue with Copilot for Power Pages", "Do not show again": "Do not show again", "Like something? Tell us more.": "Like something? Tell us more.", "Dislike something? Tell us more.": "Dislike something? Tell us more.", @@ -71,11 +73,13 @@ "Tell us more.": "Tell us more.", "Try and be as specific as possible. Your feedback will be used to improve Copilot. View privacy details ": "Try and be as specific as possible. Your feedback will be used to improve Copilot. View privacy details ", "Submit": "Submit", - "Please provide a prompt to get started.\n You can get help with writing code for Power Pages sites in HTML, CSS, and JS languages.": "Please provide a prompt to get started.\n You can get help with writing code for Power Pages sites in HTML, CSS, and JS languages.", + "Hi! Power Pages lets you build secure, professional websites that you can quickly configure and publish across web browsers and devices.\n\nTo create your website, visit the [Power Pages](https://powerpages.microsoft.com/).\nReturn to this chat and @powerpages can help you write and edit your website code.": "Hi! Power Pages lets you build secure, professional websites that you can quickly configure and publish across web browsers and devices.\n\nTo create your website, visit the [Power Pages](https://powerpages.microsoft.com/).\nReturn to this chat and @powerpages can help you write and edit your website code.", "Authentication failed. Please try again.": "Authentication failed. Please try again.", "Copilot is not available. Please contact your administrator.": "Copilot is not available. Please contact your administrator.", "Active auth profile is not found or has expired. Please try again.": "Active auth profile is not found or has expired. Please try again.", "Make sure AI-generated content is accurate and appropriate before using. [Learn more](https://go.microsoft.com/fwlink/?linkid=2240145) | [View terms](https://go.microsoft.com/fwlink/?linkid=2189520)": "Make sure AI-generated content is accurate and appropriate before using. [Learn more](https://go.microsoft.com/fwlink/?linkid=2240145) | [View terms](https://go.microsoft.com/fwlink/?linkid=2189520)", + "Explain the following code {% include 'Page Copy'%}": "Explain the following code {% include 'Page Copy'%}", + "Hi! @powerpages can help you write, edit, and even summarize your website code.": "Hi! @powerpages can help you write, edit, and even summarize your website code.", "Select Folder for new PCF Control/Do not translate 'PCF' as it is a product name.": { "message": "Select Folder for new PCF Control", "comment": [ @@ -249,4 +253,4 @@ "The {0} represents profile's Azure Cloud Instances" ] } -} +} \ No newline at end of file diff --git a/loc/translations-export/vscode-powerplatform.xlf b/loc/translations-export/vscode-powerplatform.xlf index d8f896d0..201abfda 100644 --- a/loc/translations-export/vscode-powerplatform.xlf +++ b/loc/translations-export/vscode-powerplatform.xlf @@ -79,6 +79,9 @@ Confirm + + Continue with Copilot for Power Pages + Copied to clipboard! @@ -134,6 +137,9 @@ The {3} represents Solution's Type (Managed or Unmanaged), but that test is loca Explain the following code snippet: + + Explain the following code {% include 'Page Copy'%} + Failed to create: {0}. {0} will be replaced by the error message. @@ -169,15 +175,27 @@ The {3} represents Solution's Type (Managed or Unmanaged), but that test is loca GETTING STARTED + + Get GitHub Copilot to try @powerpages + Here are a few suggestions to get you started Hi + + Hi! @powerpages can help you write, edit, and even summarize your website code. + Hi! Instantly generate code for Power Pages sites by typing in what you need. To start using Copilot, log in to your Microsoft account. + + Hi! Power Pages lets you build secure, professional websites that you can quickly configure and publish across web browsers and devices. + +To create your website, visit the [Power Pages](https://powerpages.microsoft.com/). +Return to this chat and @powerpages can help you write and edit your website code. + Hi! Your Microsoft account doesn’t currently support Copilot. Contact your admin for details. @@ -203,6 +221,10 @@ The {3} represents Solution's Type (Managed or Unmanaged), but that test is loca Login + + Make sure AI-generated content is accurate and appropriate before using. <a href="https://go.microsoft.com/fwlink/?linkid=2240145">Learn more</a> | <a href="https://go.microsoft.com/fwlink/?linkid=2189520">View + terms</a> + Make sure AI-generated content is accurate and appropriate before using. [Learn more](https://go.microsoft.com/fwlink/?linkid=2240145) | [View terms](https://go.microsoft.com/fwlink/?linkid=2189520) @@ -296,10 +318,6 @@ The {3} represents Dataverse Environment's Organization ID (GUID) Please enter a name for the webpage. - - Please provide a prompt to get started. - You can get help with writing code for Power Pages sites in HTML, CSS, and JS languages. - Power Pages Copilot is now connected to the environment: {0} : {1} {0} represents the environment name @@ -379,8 +397,8 @@ The {3} represents Dataverse Environment's Organization ID (GUID) To know more, see <a href="https://go.microsoft.com/fwlink/?linkid=2206366">Copilot in Power Pages documentation. - - Try Copilot for Power Pages + + Try @powerpages with GitHub Copilot Try again @@ -454,8 +472,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 @@ -518,12 +536,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 @@ -557,7 +575,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 @@ -613,11 +631,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 @@ -627,4 +645,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 diff --git a/package.json b/package.json index 50bb54b8..0c1f7a8b 100644 --- a/package.json +++ b/package.json @@ -119,7 +119,8 @@ "fullName": "Copilot for Power Pages", "description": "Copilot for Power Pages", "isSticky": true, - "when": "config.powerPlatform.experimental.powerPagesInGitHubCopilotChat" + "when": "config.powerPlatform.experimental.powerPagesInGitHubCopilotChat", + "sampleRequest": "How can you help with coding for my website?" } ], "problemMatchers": [ diff --git a/src/common/chat-participants/powerpages/PowerPagesChatParticipant.ts b/src/common/chat-participants/powerpages/PowerPagesChatParticipant.ts index 1c1f3c5c..55da4726 100644 --- a/src/common/chat-participants/powerpages/PowerPagesChatParticipant.ts +++ b/src/common/chat-participants/powerpages/PowerPagesChatParticipant.ts @@ -11,9 +11,9 @@ import { sendApiRequest } from '../../copilot/IntelligenceApiService'; import { PacWrapper } from '../../../client/pac/PacWrapper'; import { intelligenceAPIAuthentication } from '../../services/AuthenticationProvider'; import { ActiveOrgOutput } from '../../../client/pac/PacTypes'; -import { AUTHENTICATION_FAILED_MSG, COPILOT_NOT_AVAILABLE_MSG, DISCLAIMER_MESSAGE, NO_PROMPT_MESSAGE, PAC_AUTH_NOT_FOUND, POWERPAGES_CHAT_PARTICIPANT_ID, RESPONSE_AWAITED_MSG, SKIP_CODES, VSCODE_EXTENSION_GITHUB_POWER_PAGES_AGENT_INVOKED, VSCODE_EXTENSION_GITHUB_POWER_PAGES_AGENT_ORG_DETAILS, VSCODE_EXTENSION_GITHUB_POWER_PAGES_AGENT_ORG_DETAILS_NOT_FOUND, VSCODE_EXTENSION_GITHUB_POWER_PAGES_AGENT_SCENARIO } from './PowerPagesChatParticipantConstants'; +import { AUTHENTICATION_FAILED_MSG, COPILOT_NOT_AVAILABLE_MSG, DISCLAIMER_MESSAGE, NO_PROMPT_MESSAGE, PAC_AUTH_NOT_FOUND, POWERPAGES_CHAT_PARTICIPANT_ID, RESPONSE_AWAITED_MSG, SKIP_CODES, STATER_PROMPTS, VSCODE_EXTENSION_GITHUB_POWER_PAGES_AGENT_INVOKED, VSCODE_EXTENSION_GITHUB_POWER_PAGES_AGENT_ORG_DETAILS, VSCODE_EXTENSION_GITHUB_POWER_PAGES_AGENT_ORG_DETAILS_NOT_FOUND, VSCODE_EXTENSION_GITHUB_POWER_PAGES_AGENT_SCENARIO, WELCOME_MESSAGE, WELCOME_PROMPT } from './PowerPagesChatParticipantConstants'; import { ORG_DETAILS_KEY, handleOrgChangeSuccess, initializeOrgDetails } from '../../utilities/OrgHandlerUtils'; -import { getComponentInfo, getEndpoint } from './PowerPagesChatParticipantUtils'; +import { getComponentInfo, getEndpoint, provideChatParticipantFollowups } from './PowerPagesChatParticipantUtils'; import { checkCopilotAvailability, getActiveEditorContent } from '../../utilities/Utils'; import { IIntelligenceAPIEndpointInformation } from '../../services/Interfaces'; import { v4 as uuidv4 } from 'uuid'; @@ -42,6 +42,10 @@ export class PowerPagesChatParticipant { //TODO: Check the icon image this.chatParticipant.iconPath = vscode.Uri.joinPath(context.extensionUri, 'src', 'common', 'chat-participants', 'powerpages', 'assets', 'copilot.png'); + this.chatParticipant.followupProvider = { + provideFollowups: provideChatParticipantFollowups + }; + this.powerPagesAgentSessionId = uuidv4(); this.telemetry = telemetry; @@ -57,7 +61,6 @@ export class PowerPagesChatParticipant { this._disposables.push(orgChangeErrorEvent(async () => { this.extensionContext.globalState.update(ORG_DETAILS_KEY, { orgID: undefined, orgUrl: undefined }); })); - } public static getInstance(context: vscode.ExtensionContext, telemetry: ITelemetry | TelemetryReporter, pacWrapper?: PacWrapper) { @@ -124,25 +127,32 @@ export class PowerPagesChatParticipant { }; } - if (request.command) { - //TODO: Handle command scenarios + const userPrompt = request.prompt; - } else { + if (userPrompt === WELCOME_PROMPT) { + stream.markdown(WELCOME_MESSAGE); + return{ + metadata: { + command: STATER_PROMPTS + } + } + } - const userPrompt = request.prompt; + if (!userPrompt) { - if (!userPrompt) { + stream.markdown(NO_PROMPT_MESSAGE); - //TODO: String approval is required - stream.markdown(NO_PROMPT_MESSAGE); + return { + metadata: { + command: STATER_PROMPTS + } + }; + } - return { - metadata: { - command: '' - } - }; - } + if (request.command) { + //TODO: Handle command scenarios + } else { const { activeFileParams } = getActiveEditorContent(); const { componentInfo, entityName }: IComponentInfo = await getComponentInfo(this.telemetry, this.orgUrl, activeFileParams, this.powerPagesAgentSessionId); diff --git a/src/common/chat-participants/powerpages/PowerPagesChatParticipantConstants.ts b/src/common/chat-participants/powerpages/PowerPagesChatParticipantConstants.ts index afb3d559..5205a6b6 100644 --- a/src/common/chat-participants/powerpages/PowerPagesChatParticipantConstants.ts +++ b/src/common/chat-participants/powerpages/PowerPagesChatParticipantConstants.ts @@ -6,7 +6,7 @@ import * as vscode from 'vscode'; import { ADX_ENTITYFORM, ADX_ENTITYLIST } from '../../copilot/constants'; -export const NO_PROMPT_MESSAGE = vscode.l10n.t('Please provide a prompt to get started.\n You can get help with writing code for Power Pages sites in HTML, CSS, and JS languages.'); +export const NO_PROMPT_MESSAGE = vscode.l10n.t('Hi! Power Pages lets you build secure, professional websites that you can quickly configure and publish across web browsers and devices.\n\nTo create your website, visit the [Power Pages](https://powerpages.microsoft.com/).\nReturn to this chat and @powerpages can help you write and edit your website code.'); export const POWERPAGES_CHAT_PARTICIPANT_ID = 'powerpages'; export const RESPONSE_AWAITED_MSG = vscode.l10n.t('Working on it...'); export const AUTHENTICATION_FAILED_MSG = vscode.l10n.t('Authentication failed. Please try again.'); @@ -20,5 +20,12 @@ export const VSCODE_EXTENSION_GITHUB_POWER_PAGES_AGENT_ORG_DETAILS = 'GitHubPowe export const VSCODE_EXTENSION_GITHUB_POWER_PAGES_AGENT_ORG_DETAILS_NOT_FOUND = 'GitHubPowerPagesAgentOrgDetailsNotFound'; export const VSCODE_EXTENSION_GITHUB_POWER_PAGES_AGENT_SCENARIO = 'GitHubPowerPagesAgentScenario'; export const SKIP_CODES = ["", null, undefined, "violation", "unclear", "explain"]; +export const EXPLAIN_CODE_PROMPT = vscode.l10n.t('Explain the following code {% include \'Page Copy\'%}'); +export const WEB_API_PROMPT = vscode.l10n.t('Write web API code to query active contact records.'); +export const FORM_PROMPT = vscode.l10n.t('Write JavaScript code for form field validation to check phone field value is in the valid format.'); +export const LIST_PROMPT = vscode.l10n.t('Write JavaScript code to highlight the row where email field is empty in table list.'); +export const STATER_PROMPTS = "starterPrompts" +export const WELCOME_PROMPT = 'how can you help with coding for my website?' +export const WELCOME_MESSAGE = vscode.l10n.t('Hi! @powerpages can help you write, edit, and even summarize your website code.') diff --git a/src/common/chat-participants/powerpages/PowerPagesChatParticipantUtils.ts b/src/common/chat-participants/powerpages/PowerPagesChatParticipantUtils.ts index 96128ead..94ff0628 100644 --- a/src/common/chat-participants/powerpages/PowerPagesChatParticipantUtils.ts +++ b/src/common/chat-participants/powerpages/PowerPagesChatParticipantUtils.ts @@ -10,8 +10,9 @@ import { ITelemetry } from "../../OneDSLoggerTelemetry/telemetry/ITelemetry"; import { ArtemisService } from "../../services/ArtemisService"; import { dataverseAuthentication } from "../../services/AuthenticationProvider"; import { IIntelligenceAPIEndpointInformation } from "../../services/Interfaces"; -import { SUPPORTED_ENTITIES } from "./PowerPagesChatParticipantConstants"; -import { IComponentInfo } from "./PowerPagesChatParticipantTypes"; +import { EXPLAIN_CODE_PROMPT, FORM_PROMPT, LIST_PROMPT, STATER_PROMPTS, SUPPORTED_ENTITIES, WEB_API_PROMPT } from "./PowerPagesChatParticipantConstants"; +import { IComponentInfo, IPowerPagesChatResult } from "./PowerPagesChatParticipantTypes"; +import * as vscode from 'vscode'; export async function getEndpoint( orgID: string, @@ -55,3 +56,15 @@ export async function getComponentInfo(telemetry: ITelemetry, orgUrl: string | u export function isEntityInSupportedList(entity: string): boolean { return SUPPORTED_ENTITIES.includes(entity); } + +// eslint-disable-next-line @typescript-eslint/no-unused-vars +export function provideChatParticipantFollowups(result: IPowerPagesChatResult, _context: vscode.ChatContext, _token: vscode.CancellationToken) { + if (result.metadata.command === STATER_PROMPTS) { + return [ + { prompt: EXPLAIN_CODE_PROMPT }, + { prompt: WEB_API_PROMPT }, + { prompt: LIST_PROMPT }, + { prompt: FORM_PROMPT } + ]; + } +} diff --git a/src/common/copilot/PowerPagesCopilot.ts b/src/common/copilot/PowerPagesCopilot.ts index 2af75ebf..bd6a2ce0 100644 --- a/src/common/copilot/PowerPagesCopilot.ts +++ b/src/common/copilot/PowerPagesCopilot.ts @@ -297,7 +297,7 @@ export class PowerPagesCopilot implements vscode.WebviewViewProvider { case "openGitHubCopilotLink": { //Open the GitHub Copilot Chat with @powerpages if GitHub Copilot Chat is installed if(vscode.extensions.getExtension('github.copilot-chat')) { - vscode.commands.executeCommand('workbench.action.chat.open', '@powerpages'); + vscode.commands.executeCommand('workbench.action.chat.open', '@powerpages how can you help with coding for my website?'); } else { vscode.env.openExternal(vscode.Uri.parse('https://go.microsoft.com/fwlink/?linkid=2276973')); } diff --git a/src/common/copilot/welcome-notification/CopilotNotificationPanel.ts b/src/common/copilot/welcome-notification/CopilotNotificationPanel.ts index e2191865..bef817c2 100644 --- a/src/common/copilot/welcome-notification/CopilotNotificationPanel.ts +++ b/src/common/copilot/welcome-notification/CopilotNotificationPanel.ts @@ -4,9 +4,9 @@ */ import * as vscode from "vscode"; -import { getNonce, openWalkthrough } from "../../utilities/Utils"; +import { getNonce } from "../../utilities/Utils"; import TelemetryReporter from "@vscode/extension-telemetry"; -import { CopilotNotificationDoNotShowChecked, CopilotTryNotificationClickedEvent, CopilotWalkthroughEvent, CopilotNotificationDoNotShowUnchecked } from "../telemetry/telemetryConstants"; +import { CopilotNotificationDoNotShowChecked, CopilotTryNotificationClickedEvent, CopilotNotificationDoNotShowUnchecked } from "../telemetry/telemetryConstants"; import { COPILOT_NOTIFICATION_DISABLED } from "../constants"; import { oneDSLoggerWrapper } from "../../OneDSLoggerTelemetry/oneDSLoggerWrapper"; @@ -14,86 +14,101 @@ let NotificationPanel: vscode.WebviewPanel | undefined; export async function copilotNotificationPanel(context: vscode.ExtensionContext, telemetry: TelemetryReporter, telemetryData: string, countOfActivePortals?: string) { - if (NotificationPanel) { - NotificationPanel.dispose(); - } - - NotificationPanel = createNotificationPanel(); - - const { notificationCssUri, notificationJsUri, copilotImageUri, arrowImageUri } = getWebviewURIs(context, NotificationPanel); - - const nonce = getNonce(); - const webview = NotificationPanel.webview - NotificationPanel.webview.html = getWebviewContent(notificationCssUri, notificationJsUri, copilotImageUri, arrowImageUri, nonce, webview); - - NotificationPanel.webview.onDidReceiveMessage( - async message => { - switch (message.command) { - case 'checked': - telemetry.sendTelemetryEvent(CopilotNotificationDoNotShowChecked, { listOfOrgs: telemetryData, countOfActivePortals: countOfActivePortals as string }); - oneDSLoggerWrapper.getLogger().traceInfo(CopilotNotificationDoNotShowChecked, { listOfOrgs: telemetryData, countOfActivePortals: countOfActivePortals as string }); - context.globalState.update(COPILOT_NOTIFICATION_DISABLED, true); - break; - case 'unchecked': - telemetry.sendTelemetryEvent(CopilotNotificationDoNotShowUnchecked, { listOfOrgs: telemetryData, countOfActivePortals: countOfActivePortals as string }); - oneDSLoggerWrapper.getLogger().traceInfo(CopilotNotificationDoNotShowUnchecked, { listOfOrgs: telemetryData, countOfActivePortals: countOfActivePortals as string }); - context.globalState.update(COPILOT_NOTIFICATION_DISABLED, false); - break; - case 'tryCopilot': - telemetry.sendTelemetryEvent(CopilotTryNotificationClickedEvent, { listOfOrgs: telemetryData, countOfActivePortals: countOfActivePortals as string }); - oneDSLoggerWrapper.getLogger().traceInfo(CopilotTryNotificationClickedEvent, { listOfOrgs: telemetryData, countOfActivePortals: countOfActivePortals as string }); - vscode.commands.executeCommand('powerpages.copilot.focus') - NotificationPanel?.dispose(); - break; - case 'learnMore': - telemetry.sendTelemetryEvent(CopilotWalkthroughEvent, { listOfOrgs: telemetryData, countOfActivePortals: countOfActivePortals as string }); - openWalkthrough(context.extensionUri); - } - }, - undefined, - context.subscriptions - ); -} + if (NotificationPanel) { + NotificationPanel.dispose(); + } -function createNotificationPanel(): vscode.WebviewPanel { - const NotificationPanel = vscode.window.createWebviewPanel( - "CopilotNotification", - "Copilot in Power Pages", - { - viewColumn: vscode.ViewColumn.Beside, - preserveFocus: true, - }, - { - enableScripts: true, + NotificationPanel = createNotificationPanel(); + + const { notificationCssUri, notificationJsUri, copilotImageUri, arrowImageUri } = getWebviewURIs(context, NotificationPanel); + + const nonce = getNonce(); + const webview = NotificationPanel.webview + let isGitHubCopilotPresent = false; + let GITHUB_COPILOT_CHAT: string; + + if (vscode.extensions.getExtension('github.copilot-chat')) { + GITHUB_COPILOT_CHAT = vscode.l10n.t('Try @powerpages with GitHub Copilot'); + isGitHubCopilotPresent = true; + } else { + GITHUB_COPILOT_CHAT = vscode.l10n.t('Get GitHub Copilot to try @powerpages'); } - ); - return NotificationPanel; + NotificationPanel.webview.html = getWebviewContent(notificationCssUri, notificationJsUri, copilotImageUri, arrowImageUri, nonce, webview, GITHUB_COPILOT_CHAT); + + NotificationPanel.webview.onDidReceiveMessage( + async message => { + switch (message.command) { + case 'checked': + telemetry.sendTelemetryEvent(CopilotNotificationDoNotShowChecked, { listOfOrgs: telemetryData, countOfActivePortals: countOfActivePortals as string }); + oneDSLoggerWrapper.getLogger().traceInfo(CopilotNotificationDoNotShowChecked, { listOfOrgs: telemetryData, countOfActivePortals: countOfActivePortals as string }); + context.globalState.update(COPILOT_NOTIFICATION_DISABLED, true); + break; + case 'unchecked': + telemetry.sendTelemetryEvent(CopilotNotificationDoNotShowUnchecked, { listOfOrgs: telemetryData, countOfActivePortals: countOfActivePortals as string }); + oneDSLoggerWrapper.getLogger().traceInfo(CopilotNotificationDoNotShowUnchecked, { listOfOrgs: telemetryData, countOfActivePortals: countOfActivePortals as string }); + context.globalState.update(COPILOT_NOTIFICATION_DISABLED, false); + break; + case 'tryCopilot': + telemetry.sendTelemetryEvent(CopilotTryNotificationClickedEvent, { listOfOrgs: telemetryData, countOfActivePortals: countOfActivePortals as string }); + oneDSLoggerWrapper.getLogger().traceInfo(CopilotTryNotificationClickedEvent, { listOfOrgs: telemetryData, countOfActivePortals: countOfActivePortals as string }); + vscode.commands.executeCommand('powerpages.copilot.focus') + NotificationPanel?.dispose(); + break; + case 'learnMore': + // telemetry.sendTelemetryEvent(CopilotWalkthroughEvent, { listOfOrgs: telemetryData, countOfActivePortals: countOfActivePortals as string }); + // openWalkthrough(context.extensionUri); + if (isGitHubCopilotPresent) { + vscode.commands.executeCommand('workbench.action.chat.open', '@powerpages how can you help with coding for my website?'); + } else { + vscode.env.openExternal(vscode.Uri.parse('https://go.microsoft.com/fwlink/?linkid=2276973')); + } + } + }, + undefined, + context.subscriptions + ); +} + +function createNotificationPanel(): vscode.WebviewPanel { + const NotificationPanel = vscode.window.createWebviewPanel( + "CopilotNotification", + "Copilot in Power Pages", + { + viewColumn: vscode.ViewColumn.Beside, + preserveFocus: true, + }, + { + enableScripts: true, + } + ); + + return NotificationPanel; } function getWebviewURIs(context: vscode.ExtensionContext, NotificationPanel: vscode.WebviewPanel): { notificationCssUri: vscode.Uri, notificationJsUri: vscode.Uri, copilotImageUri: vscode.Uri, arrowImageUri: vscode.Uri } { - const srcPath = vscode.Uri.joinPath(context.extensionUri, 'src', 'common', 'copilot', "welcome-notification"); + const srcPath = vscode.Uri.joinPath(context.extensionUri, 'src', 'common', 'copilot', "welcome-notification"); - const notificationCssPath = vscode.Uri.joinPath(srcPath, "copilotNotification.css"); - const notificationCssUri = NotificationPanel.webview.asWebviewUri(notificationCssPath); + const notificationCssPath = vscode.Uri.joinPath(srcPath, "copilotNotification.css"); + const notificationCssUri = NotificationPanel.webview.asWebviewUri(notificationCssPath); - const notificationJsPath = vscode.Uri.joinPath(srcPath, "copilotNotification.js"); - const notificationJsUri = NotificationPanel.webview.asWebviewUri(notificationJsPath); + const notificationJsPath = vscode.Uri.joinPath(srcPath, "copilotNotification.js"); + const notificationJsUri = NotificationPanel.webview.asWebviewUri(notificationJsPath); - const copilotImagePath = vscode.Uri.joinPath(srcPath, "notification.svg"); - const copilotImageUri = NotificationPanel.webview.asWebviewUri(copilotImagePath); + const copilotImagePath = vscode.Uri.joinPath(srcPath, "notification.svg"); + const copilotImageUri = NotificationPanel.webview.asWebviewUri(copilotImagePath); - const arrowImagePath = vscode.Uri.joinPath(srcPath, "arrow.svg"); - const arrowImageUri = NotificationPanel.webview.asWebviewUri(arrowImagePath); + const arrowImagePath = vscode.Uri.joinPath(srcPath, "arrow.svg"); + const arrowImageUri = NotificationPanel.webview.asWebviewUri(arrowImagePath); - return { notificationCssUri, notificationJsUri, copilotImageUri, arrowImageUri }; + return { notificationCssUri, notificationJsUri, copilotImageUri, arrowImageUri }; } -function getWebviewContent(notificationCssUri: vscode.Uri, notificationJsUri: vscode.Uri, copilotImageUri: vscode.Uri, arrowImageUri: vscode.Uri, nonce: string, webview: vscode.Webview) { +function getWebviewContent(notificationCssUri: vscode.Uri, notificationJsUri: vscode.Uri, copilotImageUri: vscode.Uri, arrowImageUri: vscode.Uri, nonce: string, webview: vscode.Webview, GITHUB_COPILOT_CHAT: string) { - return ` + return ` @@ -108,8 +123,8 @@ function getWebviewContent(notificationCssUri: vscode.Uri, notificationJsUri: vs

${vscode.l10n.t("Let Copilot help you code")}

${vscode.l10n.t("Whether it’s HTML, CSS, JS, or Liquid code, just describe what you need and let AI build it for you. ")}

- - ${vscode.l10n.t("Learn more about Copilot")} + + ${vscode.l10n.t(GITHUB_COPILOT_CHAT)}
Image @@ -126,9 +141,9 @@ function getWebviewContent(notificationCssUri: vscode.Uri, notificationJsUri: vs } export function disposeNotificationPanel() { - if (NotificationPanel) { - NotificationPanel.dispose(); - NotificationPanel = undefined; - } + if (NotificationPanel) { + NotificationPanel.dispose(); + NotificationPanel = undefined; + } }