@@ -11,6 +11,10 @@ import { contextKey, setContext } from '../shared/vscode/setContext'
1111import { NotificationType , ToolkitNotification } from './types'
1212import { ToolkitError } from '../shared/errors'
1313import { isAmazonQ } from '../shared/extensionUtilities'
14+ import { getLogger } from '../shared/logger/logger'
15+ import { tempDirPath } from '../shared/filesystemUtilities'
16+ import path from 'path'
17+ import fs from '../shared/fs/fs'
1418
1519/**
1620 * Controls the "Notifications" side panel/tree in each extension. It takes purely UX actions
@@ -129,12 +133,105 @@ export class NotificationsNode implements TreeNode {
129133 *
130134 * TODO: implement more rendering possibilites.
131135 */
132- private async openNotification ( notification : ToolkitNotification ) {
133- await vscode . window . showTextDocument (
134- await vscode . workspace . openTextDocument ( {
135- content : notification . uiRenderInstructions . content [ 'en-US' ] . description ,
136- } )
136+ public async openNotification ( notification : ToolkitNotification ) {
137+ switch ( notification . uiRenderInstructions . onClick . type ) {
138+ case 'modal' :
139+ // Handle modal case
140+ await this . renderModal ( notification )
141+ break
142+ case 'openUrl' :
143+ if ( ! notification . uiRenderInstructions . onClick . url ) {
144+ throw new ToolkitError ( 'No url provided for onclick open url' )
145+ }
146+ // Handle openUrl case
147+ await vscode . env . openExternal ( vscode . Uri . parse ( notification . uiRenderInstructions . onClick . url ) )
148+ break
149+ case 'openTextDocument' :
150+ // Handle openTextDocument case
151+ await this . showReadonlyTextDocument ( notification . uiRenderInstructions . content [ 'en-US' ] . description )
152+ break
153+ }
154+ }
155+
156+ /**
157+ * Shows a read only txt file for the contect of notification on a side column
158+ * It's read-only so that the "save" option doesn't appear when user closes the notification
159+ */
160+ private async showReadonlyTextDocument ( content : string ) : Promise < void > {
161+ getLogger ( 'notifications' ) . info ( 'showing txt document ... ' )
162+ try {
163+ const tempFilePath = path . join ( tempDirPath , 'AWSToolkitNotifications.txt' )
164+
165+ if ( await fs . existsFile ( tempFilePath ) ) {
166+ // If file exist, make sure it has write permission (0o644)
167+ await fs . chmod ( tempFilePath , 0o644 )
168+ }
169+
170+ await fs . writeFile ( tempFilePath , content )
171+
172+ // Set the file permissions to read-only (0o444)
173+ await fs . chmod ( tempFilePath , 0o444 )
174+
175+ // Now, open the document
176+ const document = await vscode . workspace . openTextDocument ( tempFilePath )
177+
178+ const options : vscode . TextDocumentShowOptions = {
179+ viewColumn : vscode . ViewColumn . Beside ,
180+ preserveFocus : true ,
181+ preview : true ,
182+ }
183+
184+ await vscode . window . showTextDocument ( document , options )
185+ } catch ( error ) {
186+ throw new ToolkitError ( `Error showing text document: ${ error } ` )
187+ }
188+ }
189+
190+ public async renderModal ( notification : ToolkitNotification ) {
191+ getLogger ( 'notifications' ) . info ( 'rendering modal ... ' )
192+ if ( ! notification . uiRenderInstructions . buttons ) {
193+ throw new ToolkitError ( 'no button defined for modal' )
194+ return
195+ }
196+
197+ const buttons = notification . uiRenderInstructions . buttons
198+
199+ const buttonLabels = buttons . map ( ( buttons ) => buttons . displayText [ 'en-US' ] )
200+
201+ const detail = notification . uiRenderInstructions . content [ 'en-US' ] . description
202+
203+ const selectedButton = await vscode . window . showInformationMessage (
204+ notification . uiRenderInstructions . content [ 'en-US' ] . title ,
205+ { modal : true , detail } ,
206+ ...buttonLabels
137207 )
208+
209+ if ( selectedButton ) {
210+ const buttons = notification . uiRenderInstructions . buttons . find (
211+ ( buttons ) => buttons . displayText [ 'en-US' ] === selectedButton
212+ )
213+
214+ if ( buttons ) {
215+ switch ( buttons . type ) {
216+ case 'updateAndReload' :
217+ await this . updateAndReload ( notification . displayIf . extensionId )
218+ break
219+ case 'openUrl' :
220+ if ( buttons . url ) {
221+ await vscode . env . openExternal ( vscode . Uri . parse ( buttons . url ) )
222+ }
223+ break
224+ default :
225+ getLogger ( ) . warn ( `Unhandled button type: ${ buttons . type } ` )
226+ }
227+ }
228+ }
229+ }
230+
231+ private async updateAndReload ( id : string ) {
232+ getLogger ( 'notifications' ) . info ( 'Updating and reloading the extension...' )
233+ await vscode . commands . executeCommand ( 'workbench.extensions.installExtension' , id )
234+ await vscode . commands . executeCommand ( 'workbench.action.reloadWindow' )
138235 }
139236
140237 /**
0 commit comments