55using System . Diagnostics ;
66using System . Net ;
77using Aspire . Dashboard . Components . Dialogs ;
8+ using Aspire . Dashboard . Components . Pages ;
89using Aspire . Dashboard . Model ;
10+ using Aspire . Dashboard . Telemetry ;
911using Aspire . Dashboard . Utils ;
1012using Aspire . DashboardService . Proto . V1 ;
1113using Markdig ;
@@ -22,8 +24,20 @@ public class InteractionsProvider : ComponentBase, IAsyncDisposable
2224{
2325 private static readonly MarkdownPipeline s_markdownPipeline = MarkdownHelpers . CreateMarkdownPipelineBuilder ( ) . Build ( ) ;
2426
25- internal record InteractionMessageBarReference ( int InteractionId , Message Message ) ;
26- internal record InteractionDialogReference ( int InteractionId , IDialogReference Dialog ) ;
27+ internal record InteractionMessageBarReference ( int InteractionId , Message Message , ComponentTelemetryContext TelemetryContext ) : IDisposable
28+ {
29+ public void Dispose ( )
30+ {
31+ TelemetryContext ? . Dispose ( ) ;
32+ }
33+ }
34+ internal record InteractionDialogReference ( int InteractionId , IDialogReference Dialog , ComponentTelemetryContext TelemetryContext ) : IDisposable
35+ {
36+ public void Dispose ( )
37+ {
38+ TelemetryContext ? . Dispose ( ) ;
39+ }
40+ }
2741
2842 private readonly CancellationTokenSource _cts = new ( ) ;
2943 private readonly SemaphoreSlim _semaphore = new SemaphoreSlim ( 1 , 1 ) ;
@@ -53,6 +67,9 @@ internal record InteractionDialogReference(int InteractionId, IDialogReference D
5367 [ Inject ]
5468 public required ILogger < InteractionsProvider > Logger { get ; init ; }
5569
70+ [ Inject ]
71+ public required ComponentTelemetryContextProvider TelemetryContextProvider { get ; init ; }
72+
5673 protected override void OnInitialized ( )
5774 {
5875 // Exit quickly if the dashboard client is not enabled. For example, the dashboard is running in the standalone container.
@@ -119,6 +136,7 @@ private async Task InteractionsDisplayAsync()
119136 _pendingInteractions . RemoveAt ( 0 ) ;
120137
121138 Func < IDialogService , Task < IDialogReference > > openDialog ;
139+ string dialogComponentId ;
122140
123141 if ( item . MessageBox is { } messageBox )
124142 {
@@ -184,6 +202,7 @@ private async Task InteractionsDisplayAsync()
184202 break ;
185203 }
186204
205+ dialogComponentId = TelemetryComponentIds . InteractionMessageBox ;
187206 openDialog = dialogService => ShowMessageBoxAsync ( dialogService , content , dialogParameters ) ;
188207 }
189208 else if ( item . InputsDialog is { } inputs )
@@ -222,6 +241,7 @@ private async Task InteractionsDisplayAsync()
222241 }
223242 } ) ;
224243
244+ dialogComponentId = TelemetryComponentIds . InteractionInputsDialog ;
225245 openDialog = dialogService => dialogService . ShowDialogAsync < InteractionsInputDialog > ( vm , dialogParameters ) ;
226246 }
227247 else
@@ -236,7 +256,7 @@ await InvokeAsync(async () =>
236256 } ) ;
237257
238258 Debug . Assert ( currentDialogReference != null , "Dialog should have been created in UI thread." ) ;
239- _interactionDialogReference = new InteractionDialogReference ( item . InteractionId , currentDialogReference ) ;
259+ _interactionDialogReference = new InteractionDialogReference ( item . InteractionId , currentDialogReference , CreateTelemetryContext ( dialogComponentId ) ) ;
240260 }
241261 finally
242262 {
@@ -254,6 +274,7 @@ await InvokeAsync(async () =>
254274 {
255275 if ( _interactionDialogReference ? . Dialog == currentDialogReference )
256276 {
277+ _interactionDialogReference . Dispose ( ) ;
257278 _interactionDialogReference = null ;
258279 }
259280 }
@@ -270,6 +291,13 @@ await InvokeAsync(async () =>
270291 }
271292 }
272293
294+ private ComponentTelemetryContext CreateTelemetryContext ( string componentId )
295+ {
296+ var telemetryContext = new ComponentTelemetryContext ( ComponentType . Control , componentId ) ;
297+ TelemetryContextProvider . Initialize ( telemetryContext ) ;
298+ return telemetryContext ;
299+ }
300+
273301 private static string GetMessageHtml ( WatchInteractionsResponseUpdate item )
274302 {
275303 if ( ! item . EnableMessageMarkdown )
@@ -401,6 +429,7 @@ await InvokeAsync(async () =>
401429 }
402430
403431 _openMessageBars . Remove ( item . InteractionId ) ;
432+ openMessageBar . Dispose ( ) ;
404433
405434 await DashboardClient . SendInteractionRequestAsync ( request , _cts . Token ) . ConfigureAwait ( false ) ;
406435 }
@@ -409,7 +438,7 @@ await InvokeAsync(async () =>
409438 } ) ;
410439
411440 Debug . Assert ( message != null , "Message should have been created in UI thread." ) ;
412- _openMessageBars . Add ( new InteractionMessageBarReference ( item . InteractionId , message ) ) ;
441+ _openMessageBars . Add ( new InteractionMessageBarReference ( item . InteractionId , message , CreateTelemetryContext ( TelemetryComponentIds . InteractionMessageBar ) ) ) ;
413442 break ;
414443 case WatchInteractionsResponseUpdate . KindOneofCase . Complete :
415444 // Complete interaction.
@@ -428,6 +457,7 @@ await InvokeAsync(async () =>
428457 }
429458 finally
430459 {
460+ _interactionDialogReference . Dispose ( ) ;
431461 _interactionDialogReference = null ;
432462 }
433463 }
0 commit comments