66import { asCSSUrl } from '../../../../../base/browser/cssValue.js' ;
77import * as dom from '../../../../../base/browser/dom.js' ;
88import { createCSSRule } from '../../../../../base/browser/domStylesheets.js' ;
9- import { StandardKeyboardEvent } from '../../../../../base/browser/keyboardEvent.js' ;
109import { IRenderedMarkdown } from '../../../../../base/browser/markdownRenderer.js' ;
1110import { Button } from '../../../../../base/browser/ui/button/button.js' ;
1211import { renderIcon } from '../../../../../base/browser/ui/iconLabel/iconLabels.js' ;
13- import { Action , IAction } from '../../../../../base/common/actions.js' ;
14- import { Codicon } from '../../../../../base/common/codicons.js' ;
1512import { Event } from '../../../../../base/common/event.js' ;
1613import { StringSHA1 } from '../../../../../base/common/hash.js' ;
1714import { IMarkdownString } from '../../../../../base/common/htmlContent.js' ;
18- import { KeyCode } from '../../../../../base/common/keyCodes.js' ;
1915import { Disposable , DisposableStore } from '../../../../../base/common/lifecycle.js' ;
2016import { IObservable , ISettableObservable , observableValue } from '../../../../../base/common/observable.js' ;
2117import { ThemeIcon } from '../../../../../base/common/themables.js' ;
2218import { URI } from '../../../../../base/common/uri.js' ;
23- import { localize } from '../../../../../nls.js' ;
2419import { IContextKeyService } from '../../../../../platform/contextkey/common/contextkey.js' ;
25- import { IContextMenuService } from '../../../../../platform/contextview/browser/contextView.js' ;
2620import { IInstantiationService } from '../../../../../platform/instantiation/common/instantiation.js' ;
2721import { ILogService } from '../../../../../platform/log/common/log.js' ;
2822import { IMarkdownRendererService } from '../../../../../platform/markdown/browser/markdownRenderer.js' ;
2923import { IOpenerService } from '../../../../../platform/opener/common/opener.js' ;
30- import { ITelemetryService } from '../../../../../platform/telemetry/common/telemetry.js' ;
3124import { defaultButtonStyles } from '../../../../../platform/theme/browser/defaultStyles.js' ;
3225import { ChatAgentLocation } from '../../common/constants.js' ;
33- import { IChatWidgetService } from '../chat.js' ;
3426import { chatViewsWelcomeRegistry , IChatViewsWelcomeDescriptor } from './chatViewsWelcome.js' ;
3527
3628const $ = dom . $ ;
@@ -133,18 +125,9 @@ export interface IChatViewWelcomeContent {
133125 readonly additionalMessage ?: string | IMarkdownString ;
134126 tips ?: IMarkdownString ;
135127 readonly inputPart ?: HTMLElement ;
136- readonly suggestedPrompts ?: readonly IChatSuggestedPrompts [ ] ;
137128 readonly useLargeIcon ?: boolean ;
138129}
139130
140- export interface IChatSuggestedPrompts {
141- readonly icon ?: ThemeIcon ;
142- readonly label : string ;
143- readonly description ?: string ;
144- readonly prompt : string ;
145- readonly uri ?: URI ;
146- }
147-
148131export interface IChatViewWelcomeRenderOptions {
149132 readonly firstLinkToButton ?: boolean ;
150133 readonly location : ChatAgentLocation ;
@@ -159,10 +142,7 @@ export class ChatViewWelcomePart extends Disposable {
159142 options : IChatViewWelcomeRenderOptions | undefined ,
160143 @IOpenerService private openerService : IOpenerService ,
161144 @ILogService private logService : ILogService ,
162- @IChatWidgetService private chatWidgetService : IChatWidgetService ,
163- @ITelemetryService private telemetryService : ITelemetryService ,
164145 @IMarkdownRendererService private readonly markdownRendererService : IMarkdownRendererService ,
165- @IContextMenuService private readonly contextMenuService : IContextMenuService ,
166146 ) {
167147 super ( ) ;
168148
@@ -213,88 +193,6 @@ export class ChatViewWelcomePart extends Disposable {
213193 }
214194 }
215195
216- // Render suggested prompts for both new user and regular modes
217- if ( content . suggestedPrompts && content . suggestedPrompts . length ) {
218- const suggestedPromptsContainer = dom . append ( this . element , $ ( '.chat-welcome-view-suggested-prompts' ) ) ;
219- const titleElement = dom . append ( suggestedPromptsContainer , $ ( '.chat-welcome-view-suggested-prompts-title' ) ) ;
220- titleElement . textContent = localize ( 'chatWidget.suggestedActions' , 'Suggested Actions' ) ;
221-
222- for ( const prompt of content . suggestedPrompts ) {
223- const promptElement = dom . append ( suggestedPromptsContainer , $ ( '.chat-welcome-view-suggested-prompt' ) ) ;
224- // Make the prompt element keyboard accessible
225- promptElement . setAttribute ( 'role' , 'button' ) ;
226- promptElement . setAttribute ( 'tabindex' , '0' ) ;
227- const promptAriaLabel = prompt . description
228- ? localize ( 'suggestedPromptAriaLabelWithDescription' , 'Suggested prompt: {0}, {1}' , prompt . label , prompt . description )
229- : localize ( 'suggestedPromptAriaLabel' , 'Suggested prompt: {0}' , prompt . label ) ;
230- promptElement . setAttribute ( 'aria-label' , promptAriaLabel ) ;
231- const titleElement = dom . append ( promptElement , $ ( '.chat-welcome-view-suggested-prompt-title' ) ) ;
232- titleElement . textContent = prompt . label ;
233- const tooltip = localize ( 'runPromptTitle' , "Suggested prompt: {0}" , prompt . prompt ) ;
234- promptElement . title = tooltip ;
235- titleElement . title = tooltip ;
236- if ( prompt . description ) {
237- const descriptionElement = dom . append ( promptElement , $ ( '.chat-welcome-view-suggested-prompt-description' ) ) ;
238- descriptionElement . textContent = prompt . description ;
239- descriptionElement . title = prompt . description ;
240- }
241- const executePrompt = ( ) => {
242- type SuggestedPromptClickEvent = { suggestedPrompt : string } ;
243-
244- type SuggestedPromptClickData = {
245- owner : 'bhavyaus' ;
246- comment : 'Event used to gain insights into when suggested prompts are clicked.' ;
247- suggestedPrompt : { classification : 'SystemMetaData' ; purpose : 'FeatureInsight' ; comment : 'The suggested prompt clicked.' } ;
248- } ;
249-
250- this . telemetryService . publicLog2 < SuggestedPromptClickEvent , SuggestedPromptClickData > ( 'chat.clickedSuggestedPrompt' , {
251- suggestedPrompt : prompt . prompt ,
252- } ) ;
253-
254- if ( ! this . chatWidgetService . lastFocusedWidget ) {
255- const widgets = this . chatWidgetService . getWidgetsByLocations ( ChatAgentLocation . Chat ) ;
256- if ( widgets . length ) {
257- widgets [ 0 ] . setInput ( prompt . prompt ) ;
258- }
259- } else {
260- this . chatWidgetService . lastFocusedWidget . setInput ( prompt . prompt ) ;
261- }
262- } ;
263- // Add context menu handler
264- this . _register ( dom . addDisposableListener ( promptElement , dom . EventType . CONTEXT_MENU , ( e : MouseEvent ) => {
265- e . preventDefault ( ) ;
266- e . stopImmediatePropagation ( ) ;
267-
268- const actions = this . getPromptContextMenuActions ( prompt ) ;
269-
270- this . contextMenuService . showContextMenu ( {
271- getAnchor : ( ) => ( { x : e . clientX , y : e . clientY } ) ,
272- getActions : ( ) => actions ,
273- } ) ;
274- } ) ) ;
275- // Add click handler
276- this . _register ( dom . addDisposableListener ( promptElement , dom . EventType . CLICK , executePrompt ) ) ;
277- // Add keyboard handler
278- this . _register ( dom . addDisposableListener ( promptElement , dom . EventType . KEY_DOWN , ( e ) => {
279- const event = new StandardKeyboardEvent ( e ) ;
280- if ( event . equals ( KeyCode . Enter ) || event . equals ( KeyCode . Space ) ) {
281- e . preventDefault ( ) ;
282- e . stopPropagation ( ) ;
283- executePrompt ( ) ;
284- }
285- else if ( event . equals ( KeyCode . F10 ) && event . shiftKey ) {
286- e . preventDefault ( ) ;
287- e . stopPropagation ( ) ;
288- const actions = this . getPromptContextMenuActions ( prompt ) ;
289- this . contextMenuService . showContextMenu ( {
290- getAnchor : ( ) => promptElement ,
291- getActions : ( ) => actions ,
292- } ) ;
293- }
294- } ) ) ;
295- }
296- }
297-
298196 // Tips
299197 if ( content . tips ) {
300198 const tips = dom . append ( this . element , $ ( '.chat-welcome-view-tips' ) ) ;
@@ -306,39 +204,13 @@ export class ChatViewWelcomePart extends Disposable {
306204 }
307205 }
308206
309- private getPromptContextMenuActions ( prompt : IChatSuggestedPrompts ) : IAction [ ] {
310- const actions : IAction [ ] = [ ] ;
311- if ( prompt . uri ) {
312- const uri = prompt . uri ;
313- actions . push ( new Action (
314- 'chat.editPromptFile' ,
315- localize ( 'editPromptFile' , "Edit Prompt File" ) ,
316- ThemeIcon . asClassName ( Codicon . goToFile ) ,
317- true ,
318- async ( ) => {
319- try {
320- await this . openerService . open ( uri ) ;
321- } catch ( error ) {
322- this . logService . error ( 'Failed to open prompt file:' , error ) ;
323- }
324- }
325- ) ) ;
326- }
327- return actions ;
328- }
329-
330207 public needsRerender ( content : IChatViewWelcomeContent ) : boolean {
331208 // Heuristic based on content that changes between states
332209 return ! ! (
333210 this . content . title !== content . title ||
334211 this . content . message . value !== content . message . value ||
335212 this . content . additionalMessage !== content . additionalMessage ||
336- this . content . tips ?. value !== content . tips ?. value ||
337- this . content . suggestedPrompts ?. length !== content . suggestedPrompts ?. length ||
338- this . content . suggestedPrompts ?. some ( ( prompt , index ) => {
339- const incoming = content . suggestedPrompts ?. [ index ] ;
340- return incoming ?. label !== prompt . label || incoming ?. description !== prompt . description ;
341- } ) ) ;
213+ this . content . tips ?. value !== content . tips ?. value ) ;
342214 }
343215
344216 private renderMarkdownMessageContent ( content : IMarkdownString , options : IChatViewWelcomeRenderOptions | undefined ) : IRenderedMarkdown {
0 commit comments