Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 11 additions & 41 deletions packages/core/src/notifications/panelNode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,9 @@ import { NotificationType, ToolkitNotification } from './types'
import { ToolkitError } from '../shared/errors'
import { isAmazonQ } from '../shared/extensionUtilities'
import { getLogger } from '../shared/logger/logger'
import { tempDirPath } from '../shared/filesystemUtilities'
import path from 'path'
import fs from '../shared/fs/fs'
import { registerToolView } from '../awsexplorer/activationShared'
import { readonlyDocument } from '../shared/utilities/textDocumentUtilities'
import { openUrl } from '../shared/utilities/vsCodeUtils'

/**
* Controls the "Notifications" side panel/tree in each extension. It takes purely UX actions
Expand Down Expand Up @@ -143,49 +142,19 @@ export class NotificationsNode implements TreeNode {
}
// Show open url option
getLogger('notifications').verbose(`opening url for notification: ${notification.id} ...`)
await vscode.env.openExternal(vscode.Uri.parse(notification.uiRenderInstructions.onClick.url))
await openUrl(vscode.Uri.parse(notification.uiRenderInstructions.onClick.url))
break
case 'openTextDocument':
// Display read-only txt document
getLogger('notifications').verbose(`showing txt document for notification: ${notification.id} ...`)
await this.showReadonlyTextDocument(notification.uiRenderInstructions.content['en-US'].description)
await readonlyDocument.show(
notification.uiRenderInstructions.content['en-US'].description,
`Notification: ${notification.id}`
)
break
}
}

/**
* Shows a read only txt file for the contect of notification on a side column
* It's read-only so that the "save" option doesn't appear when user closes the notification
*/
private async showReadonlyTextDocument(content: string): Promise<void> {
try {
const tempFilePath = path.join(tempDirPath, 'AWSToolkitNotifications.txt')

if (await fs.existsFile(tempFilePath)) {
// If file exist, make sure it has write permission (0o644)
await fs.chmod(tempFilePath, 0o644)
}

await fs.writeFile(tempFilePath, content)

// Set the file permissions to read-only (0o444)
await fs.chmod(tempFilePath, 0o444)

// Now, open the document
const document = await vscode.workspace.openTextDocument(tempFilePath)

const options: vscode.TextDocumentShowOptions = {
viewColumn: vscode.ViewColumn.Beside,
preserveFocus: true,
preview: true,
}

await vscode.window.showTextDocument(document, options)
} catch (error) {
throw new ToolkitError(`Error showing text document: ${error}`)
}
}

/**
* Renders information window with the notification's content and buttons.
* Can be either a blocking modal or a bottom-right corner toast
Expand Down Expand Up @@ -217,16 +186,17 @@ export class NotificationsNode implements TreeNode {
if (selectedButton) {
switch (selectedButton.type) {
case 'openTxt':
await this.showReadonlyTextDocument(
notification.uiRenderInstructions.content['en-US'].description
await readonlyDocument.show(
notification.uiRenderInstructions.content['en-US'].description,
`Notification: ${notification.id}`
)
break
case 'updateAndReload':
await this.updateAndReload(notification.displayIf.extensionId)
break
case 'openUrl':
if (selectedButton.url) {
await vscode.env.openExternal(vscode.Uri.parse(selectedButton.url))
await openUrl(vscode.Uri.parse(selectedButton.url))
} else {
throw new ToolkitError('url not provided')
}
Expand Down
44 changes: 44 additions & 0 deletions packages/core/src/shared/utilities/textDocumentUtilities.ts
Original file line number Diff line number Diff line change
Expand Up @@ -223,3 +223,47 @@ export async function addEofNewline(editor: vscode.TextEditor) {
})
}
}

class ReadonlyTextDocumentProvider implements vscode.TextDocumentContentProvider {
private content = ''

setContent(content: string) {
this.content = content
}

provideTextDocumentContent(uri: vscode.Uri): string {
return this.content
}
}

/**
* Shows a read only virtual txt file on a side column
* It's read-only so that the "save" option doesn't appear when user closes the pop up window
* Usage: ReadonlyDocument.show(content, filename)
* @param content The content to be displayed in the virtual document
* @param filename The title on top of the pop up window
*/
class ReadonlyDocument {
private readonly scheme = 'AWStoolkit-readonly'
private readonly provider = new ReadonlyTextDocumentProvider()

constructor() {
vscode.workspace.registerTextDocumentContentProvider(this.scheme, this.provider)
}

public async show(content: string, filename: string) {
this.provider.setContent(content)
const uri = vscode.Uri.parse(`${this.scheme}:/${filename}.txt`)
const options: vscode.TextDocumentShowOptions = {
viewColumn: vscode.ViewColumn.Beside,
preserveFocus: true,
preview: true,
}

// Open the document with the updated content
const document = await vscode.workspace.openTextDocument(uri)
await vscode.window.showTextDocument(document, options)
}
}

export const readonlyDocument = new ReadonlyDocument()
62 changes: 11 additions & 51 deletions packages/core/src/test/notifications/resources/emergency/1.x.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,88 +2,48 @@
"schemaVersion": "1.x",
"notifications": [
{
"id": "amazonq_emergency_local_1",
"id": "emergency1",
"displayIf": {
"extensionId": "amazonwebservices.amazon-q-vscode"
},
"uiRenderInstructions": {
"content": {
"en-US": {
"title": "[local] Emergency: url",
"description": "Something crazy is happening! Please update your extension.",
"toastPreview": "omg"
}
},
"onRecieve": "toast",
"onClick": {
"type": "modal"
},
"actions": [
{
"type": "updateAndReload",
"displayText": {
"en-US": "Update and Reload"
}
},
{
"type": "openUrl",
"url": "https://aws.amazon.com/visualstudiocode/",
"displayText": {
"en-US": "Proceed to wiki"
}
}
]
}
},
{
"id": "amazonq_emergency_local_2",
"displayIf": {
"extensionId": "amazonwebservices.amazon-q-vscode"
},
"uiRenderInstructions": {
"content": {
"en-US": {
"title": "[local] Emergency: txt",
"description": "Something crazy is happening! Please update your extension.",
"toastPreview": "omg"
"title": "Can't sign in to Amazon Q",
"description": "There is currently a bug that is preventing users from signing into Amazon Q. If this impacts you, please try this workaround:\n\n 1. Reload your IDE\n 2. Run the command in the command palette:: `Amazon Q: Reset State`.\n 3. Set your default region to `us-east-3`.\n 4. Try to sign into Amazon Q with your desired region in the dropdown.\n\nWe are currently working on releasing a fix so that this workaround is not required.\nPlease reach out on our github issues with any questions.",
"toastPreview": "Signing into Amazon Q is broken, please try this workaround while we work on releasing a fix."
}
},
"onRecieve": "toast",
"onClick": {
"type": "openTextDocument"
}
},
"actions": []
}
},
{
"id": "amazonq_emergency_local_3",
"id": "emergency2",
"displayIf": {
"extensionId": "amazonwebservices.amazon-q-vscode"
},
"uiRenderInstructions": {
"content": {
"en-US": {
"title": "[local] Emergency: modal",
"description": "Something crazy is happening! Please update your extension.",
"toastPreview": "new notification: something crazy is happening! Please update your entension and look on our wiki."
"title": "Update Amazon Q to avoid breaking bugs",
"description": "There is currently a bug that prevents Amazon Q from responding to chat requests. It is fixed in the latest version. Please update your Amazon Q now.",
"toastPreview": "This version of Amazon Q is currently broken, please update to avoid issues."
}
},
"onRecieve": "toast",
"onClick": {
"type": "openTextDocument"
"type": "modal"
},
"actions": [
{
"type": "updateAndReload",
"displayText": {
"en-US": "Update and Reload"
}
},
{
"type": "openUrl",
"url": "https://aws.amazon.com/visualstudiocode/",
"displayText": {
"en-US": "Proceed to wiki"
}
}
]
}
Expand Down
40 changes: 34 additions & 6 deletions packages/core/src/test/notifications/resources/startup/1.x.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,51 @@
"schemaVersion": "1.x",
"notifications": [
{
"id": "amazonq_startUp_local_1",
"id": "startup1",
"displayIf": {
"extensionId": "amazonwebservices.amazon-q-vscode"
},
"uiRenderInstructions": {
"content": {
"en-US": {
"title": "[local] What's New, url",
"description": "Check out this new stuff!",
"toastPreview": "omg"
"title": "New Amazon Q Chat features",
"description": "You can now use Amazon Q inline in your IDE, without ever touching the mouse or using copy and paste. \nPress ⌘+I (Ctrl+I on Windows) to trigger inline chat. \nDescribe a function or feature you'd like to develop and Amazon Q will generate and display a code diff that inserts new code at the cursor position. \nPress Enter to accept and apply the diff, or Escape to reject it. \nAlternatively you select a block of code (maybe even the entire file) then press ⌘+I (Ctrl+I on Windows) to provide instructions on how to refactor the selected code. \nYou will see a diff against the selected code and can press Enter to accept and apply the diff.",
"toastPreview": "New Amazon Q features available: inline chat"
}
},
"onRecieve": "toast",
"onClick": {
"type": "openTextDocument"
},
"actions": [
{
"type": "openUrl",
"url": "https://aws.amazon.com/developer/generative-ai/amazon-q/change-log/",
"displayText": {
"en-US": "Learn more"
}
}
]
}
},
{
"id": "startup2",
"displayIf": {
"extensionId": "amazonwebservices.amazon-q-vscode"
},
"uiRenderInstructions": {
"content": {
"en-US": {
"title": "What's New",
"toastPreview": "New Amazon Q features are available!"
}
},
"onRecieve": "toast",
"onClick": {
"type": "openUrl",
"url": "https://aws.amazon.com/visualstudiocode/"
}
"url": "https://aws.amazon.com/developer/generative-ai/amazon-q/change-log/"
},
"actions": []
}
}
]
Expand Down
Loading