From ac2c038b04fb33a11c360eb88c0989fff6e77b9b Mon Sep 17 00:00:00 2001 From: David Hasani Date: Tue, 17 Dec 2024 14:19:26 -0800 Subject: [PATCH 1/6] feat(amazonq): add view summary button in chat --- ...Feature-1e7f3af5-7c94-4c60-8909-a61c0b06e02e.json | 4 ++++ .../src/amazonqGumby/chat/controller/controller.ts | 8 ++++++++ .../chat/controller/messenger/messenger.ts | 12 ++++++++++-- .../chat/controller/messenger/messengerUtils.ts | 1 + .../src/codewhisperer/commands/startTransformByQ.ts | 5 +++-- packages/core/src/codewhisperer/models/constants.ts | 6 ++---- .../transformationResultsViewProvider.ts | 1 - 7 files changed, 28 insertions(+), 9 deletions(-) create mode 100644 packages/amazonq/.changes/next-release/Feature-1e7f3af5-7c94-4c60-8909-a61c0b06e02e.json diff --git a/packages/amazonq/.changes/next-release/Feature-1e7f3af5-7c94-4c60-8909-a61c0b06e02e.json b/packages/amazonq/.changes/next-release/Feature-1e7f3af5-7c94-4c60-8909-a61c0b06e02e.json new file mode 100644 index 00000000000..cd8bab12485 --- /dev/null +++ b/packages/amazonq/.changes/next-release/Feature-1e7f3af5-7c94-4c60-8909-a61c0b06e02e.json @@ -0,0 +1,4 @@ +{ + "type": "Feature", + "description": "Amazon Q Code Transformation: add view summary button in chat" +} diff --git a/packages/core/src/amazonqGumby/chat/controller/controller.ts b/packages/core/src/amazonqGumby/chat/controller/controller.ts index e79ce883e0a..9cc5f603211 100644 --- a/packages/core/src/amazonqGumby/chat/controller/controller.ts +++ b/packages/core/src/amazonqGumby/chat/controller/controller.ts @@ -385,6 +385,14 @@ export class GumbyController { await vscode.commands.executeCommand(GumbyCommands.FOCUS_TRANSFORMATION_HUB, CancelActionPositions.Chat) this.messenger.sendJobSubmittedMessage(message.tabID) break + case ButtonActions.VIEW_SUMMARY: + await vscode.commands.executeCommand('aws.amazonq.transformationHub.summary.reveal') + this.transformationFinished({ + message: CodeWhispererConstants.viewProposedChangesChatMessage, + tabID: message.tabID, + includeStartNewTransformationButton: true, + }) + break case ButtonActions.STOP_TRANSFORMATION_JOB: await stopTransformByQ(transformByQState.getJobId()) await postTransformationJob() diff --git a/packages/core/src/amazonqGumby/chat/controller/messenger/messenger.ts b/packages/core/src/amazonqGumby/chat/controller/messenger/messenger.ts index 3d947b8caff..e0c46bb2455 100644 --- a/packages/core/src/amazonqGumby/chat/controller/messenger/messenger.ts +++ b/packages/core/src/amazonqGumby/chat/controller/messenger/messenger.ts @@ -243,8 +243,8 @@ export class Messenger { mandatory: true, options: [ { - value: JDKVersion.JDK17.toString(), - label: JDKVersion.JDK17.toString(), + value: JDKVersion.JDK17, + label: JDKVersion.JDK17, }, ], }) @@ -517,6 +517,14 @@ export class Messenger { }) } + if (transformByQState.getSummaryFilePath()) { + buttons.push({ + keepCardAfterClick: true, + text: CodeWhispererConstants.viewSummaryButtonText, + id: ButtonActions.VIEW_SUMMARY, + }) + } + this.dispatcher.sendChatMessage( new ChatMessage( { diff --git a/packages/core/src/amazonqGumby/chat/controller/messenger/messengerUtils.ts b/packages/core/src/amazonqGumby/chat/controller/messenger/messengerUtils.ts index 1eeef162d34..3d3c18959d3 100644 --- a/packages/core/src/amazonqGumby/chat/controller/messenger/messengerUtils.ts +++ b/packages/core/src/amazonqGumby/chat/controller/messenger/messengerUtils.ts @@ -13,6 +13,7 @@ import DependencyVersions from '../../../models/dependencies' export enum ButtonActions { STOP_TRANSFORMATION_JOB = 'gumbyStopTransformationJob', VIEW_TRANSFORMATION_HUB = 'gumbyViewTransformationHub', + VIEW_SUMMARY = 'gumbyViewSummary', CONFIRM_LANGUAGE_UPGRADE_TRANSFORMATION_FORM = 'gumbyLanguageUpgradeTransformFormConfirm', CONFIRM_SQL_CONVERSION_TRANSFORMATION_FORM = 'gumbySQLConversionTransformFormConfirm', CANCEL_TRANSFORMATION_FORM = 'gumbyTransformFormCancel', // shared between Language Upgrade & SQL Conversion diff --git a/packages/core/src/codewhisperer/commands/startTransformByQ.ts b/packages/core/src/codewhisperer/commands/startTransformByQ.ts index 47217fa928d..b00ae4a6afb 100644 --- a/packages/core/src/codewhisperer/commands/startTransformByQ.ts +++ b/packages/core/src/codewhisperer/commands/startTransformByQ.ts @@ -8,6 +8,7 @@ import * as fs from 'fs' // eslint-disable-line no-restricted-imports import path from 'path' import { getLogger } from '../../shared/logger' import * as CodeWhispererConstants from '../models/constants' +import * as localizedText from '../../shared/localizedText' import { transformByQState, StepProgress, @@ -233,7 +234,7 @@ export async function preTransformationUploadCode() { await vscode.commands.executeCommand('aws.amazonq.transformationHub.focus') void vscode.window.showInformationMessage(CodeWhispererConstants.jobStartedNotification, { - title: CodeWhispererConstants.jobStartedTitle, + title: localizedText.ok, }) let uploadId = '' @@ -750,7 +751,7 @@ export async function postTransformationJob() { if (transformByQState.isSucceeded()) { void vscode.window.showInformationMessage(CodeWhispererConstants.jobCompletedNotification(diffMessage), { - title: CodeWhispererConstants.transformationCompletedTitle, + title: localizedText.ok, }) } else if (transformByQState.isPartiallySucceeded()) { void vscode.window diff --git a/packages/core/src/codewhisperer/models/constants.ts b/packages/core/src/codewhisperer/models/constants.ts index 96e4c3438f0..236f506466a 100644 --- a/packages/core/src/codewhisperer/models/constants.ts +++ b/packages/core/src/codewhisperer/models/constants.ts @@ -554,8 +554,6 @@ export const noOngoingJobMessage = 'No ongoing job.' export const nothingToShowMessage = 'Nothing to show' -export const jobStartedTitle = 'Transformation started' - export const jobStartedNotification = 'Amazon Q is transforming your code. It can take 10 to 30 minutes to upgrade your code, depending on the size of your project. To monitor progress, go to the Transformation Hub.' @@ -563,6 +561,8 @@ export const openTransformationHubButtonText = 'Open Transformation Hub' export const startTransformationButtonText = 'Start a new transformation' +export const viewSummaryButtonText = 'View summary' + export const stopTransformationButtonText = 'Stop transformation' export const checkingForProjectsChatMessage = 'Checking for eligible projects...' @@ -638,8 +638,6 @@ export const jobCancelledChatMessage = export const jobCancelledNotification = 'You cancelled the transformation.' -export const transformationCompletedTitle = 'Transformation complete' - export const diffMessage = (multipleDiffs: boolean) => { return multipleDiffs ? 'You can review the diffs to see my proposed changes and accept or reject them. You will be able to accept changes from one diff at a time. If you reject changes in one diff, you will not be able to view or accept changes in the other diffs.' diff --git a/packages/core/src/codewhisperer/service/transformByQ/transformationResultsViewProvider.ts b/packages/core/src/codewhisperer/service/transformByQ/transformationResultsViewProvider.ts index 1f4058a54dc..fd8c7adc1f6 100644 --- a/packages/core/src/codewhisperer/service/transformByQ/transformationResultsViewProvider.ts +++ b/packages/core/src/codewhisperer/service/transformByQ/transformationResultsViewProvider.ts @@ -370,7 +370,6 @@ export class ProposedTransformationExplorer { 'markdown.showPreview', vscode.Uri.file(transformByQState.getSummaryFilePath()) ) - telemetry.ui_click.emit({ elementId: 'transformationHub_viewSummary' }) } }) From 1b5944eb8ef95d79189bfbeeba0ec5fd42c737ce Mon Sep 17 00:00:00 2001 From: David Hasani Date: Wed, 18 Dec 2024 11:49:56 -0800 Subject: [PATCH 2/6] add test --- .../test/e2e/amazonq/transformByQ.test.ts | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/packages/amazonq/test/e2e/amazonq/transformByQ.test.ts b/packages/amazonq/test/e2e/amazonq/transformByQ.test.ts index 69fc905c985..b6a49503d21 100644 --- a/packages/amazonq/test/e2e/amazonq/transformByQ.test.ts +++ b/packages/amazonq/test/e2e/amazonq/transformByQ.test.ts @@ -12,6 +12,7 @@ import { GumbyController, setMaven, startTransformByQ, TabsStorage } from 'aws-c import { using, registerAuthHook, TestFolder } from 'aws-core-vscode/test' import { loginToIdC } from './utils/setup' import { fs } from 'aws-core-vscode/shared' +import * as os from 'os' import path from 'path' describe('Amazon Q Code Transformation', function () { @@ -153,6 +154,21 @@ describe('Amazon Q Code Transformation', function () { const jdkPathResponse = tab.getChatItems().pop() // this 'Sorry' message is OK - just making sure that the UI components are working correctly assert.strictEqual(jdkPathResponse?.body?.includes("Sorry, I couldn't locate your Java installation"), true) + + transformByQState.setSummaryFilePath(path.join(os.tmpdir(), 'summary.md')) + + tab.clickCustomFormButton({ + id: 'gumbyViewSummary', + text: 'View summary', + }) + + await tab.waitForEvent(() => tab.getChatItems().length > 14, { + waitTimeoutInMs: 5000, + waitIntervalInMs: 1000, + }) + + const viewSummaryChatItem = tab.getChatItems().pop() + assert.strictEqual(viewSummaryChatItem?.body?.includes('view a summary'), true) }) it('Can provide metadata file for a SQL conversion', async () => { From 36255d67977b9d72a780f98698af81de26903caf Mon Sep 17 00:00:00 2001 From: David Hasani Date: Thu, 19 Dec 2024 12:33:51 -0800 Subject: [PATCH 3/6] use TestFolder --- packages/amazonq/test/e2e/amazonq/transformByQ.test.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/amazonq/test/e2e/amazonq/transformByQ.test.ts b/packages/amazonq/test/e2e/amazonq/transformByQ.test.ts index b6a49503d21..704e25e668e 100644 --- a/packages/amazonq/test/e2e/amazonq/transformByQ.test.ts +++ b/packages/amazonq/test/e2e/amazonq/transformByQ.test.ts @@ -12,7 +12,6 @@ import { GumbyController, setMaven, startTransformByQ, TabsStorage } from 'aws-c import { using, registerAuthHook, TestFolder } from 'aws-core-vscode/test' import { loginToIdC } from './utils/setup' import { fs } from 'aws-core-vscode/shared' -import * as os from 'os' import path from 'path' describe('Amazon Q Code Transformation', function () { @@ -155,7 +154,9 @@ describe('Amazon Q Code Transformation', function () { // this 'Sorry' message is OK - just making sure that the UI components are working correctly assert.strictEqual(jdkPathResponse?.body?.includes("Sorry, I couldn't locate your Java installation"), true) - transformByQState.setSummaryFilePath(path.join(os.tmpdir(), 'summary.md')) + const tmpDir = (await TestFolder.create()).path + + transformByQState.setSummaryFilePath(path.join(tmpDir, 'summary.md')) tab.clickCustomFormButton({ id: 'gumbyViewSummary', From 2dfd46175b4aa6ae546ba28d54a107d2514a4f27 Mon Sep 17 00:00:00 2001 From: David Hasani Date: Tue, 31 Dec 2024 08:18:41 -0800 Subject: [PATCH 4/6] set disabled to false --- .../core/src/amazonqGumby/chat/controller/controller.ts | 6 ------ .../amazonqGumby/chat/controller/messenger/messenger.ts | 7 +++++-- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/packages/core/src/amazonqGumby/chat/controller/controller.ts b/packages/core/src/amazonqGumby/chat/controller/controller.ts index 9cc5f603211..e75f87f3223 100644 --- a/packages/core/src/amazonqGumby/chat/controller/controller.ts +++ b/packages/core/src/amazonqGumby/chat/controller/controller.ts @@ -383,15 +383,9 @@ export class GumbyController { break case ButtonActions.VIEW_TRANSFORMATION_HUB: await vscode.commands.executeCommand(GumbyCommands.FOCUS_TRANSFORMATION_HUB, CancelActionPositions.Chat) - this.messenger.sendJobSubmittedMessage(message.tabID) break case ButtonActions.VIEW_SUMMARY: await vscode.commands.executeCommand('aws.amazonq.transformationHub.summary.reveal') - this.transformationFinished({ - message: CodeWhispererConstants.viewProposedChangesChatMessage, - tabID: message.tabID, - includeStartNewTransformationButton: true, - }) break case ButtonActions.STOP_TRANSFORMATION_JOB: await stopTransformByQ(transformByQState.getJobId()) diff --git a/packages/core/src/amazonqGumby/chat/controller/messenger/messenger.ts b/packages/core/src/amazonqGumby/chat/controller/messenger/messenger.ts index e0c46bb2455..ac12b070803 100644 --- a/packages/core/src/amazonqGumby/chat/controller/messenger/messenger.ts +++ b/packages/core/src/amazonqGumby/chat/controller/messenger/messenger.ts @@ -376,19 +376,20 @@ export class Messenger { ) { const buttons: ChatItemButton[] = [] + // don't show these buttons when server build fails if (!disableJobActions) { - // Note: buttons can only be clicked once. - // To get around this, we remove the card after it's clicked and then resubmit the message. buttons.push({ keepCardAfterClick: true, text: CodeWhispererConstants.openTransformationHubButtonText, id: ButtonActions.VIEW_TRANSFORMATION_HUB, + disabled: false, // allow button to be re-clicked }) buttons.push({ keepCardAfterClick: true, text: CodeWhispererConstants.stopTransformationButtonText, id: ButtonActions.STOP_TRANSFORMATION_JOB, + disabled: false, }) } @@ -514,6 +515,7 @@ export class Messenger { keepCardAfterClick: false, text: CodeWhispererConstants.startTransformationButtonText, id: ButtonActions.CONFIRM_START_TRANSFORMATION_FLOW, + disabled: false, }) } @@ -522,6 +524,7 @@ export class Messenger { keepCardAfterClick: true, text: CodeWhispererConstants.viewSummaryButtonText, id: ButtonActions.VIEW_SUMMARY, + disabled: false, }) } From 21035da2c36e2d78d21f8cec0b7e47092a79a399 Mon Sep 17 00:00:00 2001 From: David Hasani Date: Tue, 31 Dec 2024 10:28:40 -0800 Subject: [PATCH 5/6] fix e2e test --- .../service/transformByQ/transformationResultsViewProvider.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/core/src/codewhisperer/service/transformByQ/transformationResultsViewProvider.ts b/packages/core/src/codewhisperer/service/transformByQ/transformationResultsViewProvider.ts index fd8c7adc1f6..d0e95e768be 100644 --- a/packages/core/src/codewhisperer/service/transformByQ/transformationResultsViewProvider.ts +++ b/packages/core/src/codewhisperer/service/transformByQ/transformationResultsViewProvider.ts @@ -365,7 +365,7 @@ export class ProposedTransformationExplorer { }) vscode.commands.registerCommand('aws.amazonq.transformationHub.summary.reveal', async () => { - if (transformByQState.getSummaryFilePath() !== '') { + if (fs.existsSync(transformByQState.getSummaryFilePath())) { await vscode.commands.executeCommand( 'markdown.showPreview', vscode.Uri.file(transformByQState.getSummaryFilePath()) From 131dad96798b7e5a555a3d5ae8639d60ed9d88d4 Mon Sep 17 00:00:00 2001 From: David Hasani Date: Tue, 31 Dec 2024 10:29:56 -0800 Subject: [PATCH 6/6] fix e2e test --- .../amazonq/test/e2e/amazonq/transformByQ.test.ts | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/packages/amazonq/test/e2e/amazonq/transformByQ.test.ts b/packages/amazonq/test/e2e/amazonq/transformByQ.test.ts index 704e25e668e..b28368e1e7f 100644 --- a/packages/amazonq/test/e2e/amazonq/transformByQ.test.ts +++ b/packages/amazonq/test/e2e/amazonq/transformByQ.test.ts @@ -7,7 +7,12 @@ import assert from 'assert' import { qTestingFramework } from './framework/framework' import sinon from 'sinon' import { Messenger } from './framework/messenger' -import { JDKVersion, TransformationType, transformByQState } from 'aws-core-vscode/codewhisperer' +import { + CodeWhispererConstants, + JDKVersion, + TransformationType, + transformByQState, +} from 'aws-core-vscode/codewhisperer' import { GumbyController, setMaven, startTransformByQ, TabsStorage } from 'aws-core-vscode/amazonqGumby' import { using, registerAuthHook, TestFolder } from 'aws-core-vscode/test' import { loginToIdC } from './utils/setup' @@ -158,6 +163,10 @@ describe('Amazon Q Code Transformation', function () { transformByQState.setSummaryFilePath(path.join(tmpDir, 'summary.md')) + transformByQState + .getChatMessenger() + ?.sendJobFinishedMessage(tab.tabID, CodeWhispererConstants.viewProposedChangesChatMessage) + tab.clickCustomFormButton({ id: 'gumbyViewSummary', text: 'View summary',