|
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System.Globalization;
using Aspire.Dashboard.Extensions;
using Aspire.Dashboard.Model;
using Aspire.Hosting.ConsoleLogs;
using Microsoft.AspNetCore.Components;
using Microsoft.JSInterop;
namespace Aspire.Dashboard.Components;
/// <summary>
/// A log viewing UI component that shows a live view of a log, with syntax highlighting and automatic scrolling.
/// </summary>
public sealed partial class LogViewer
{
private readonly bool _convertTimestampsFromUtc = true;
private LogEntries? _logEntries;
private bool _logsChanged;
[Inject]
public required BrowserTimeProvider TimeProvider { get; init; }
[Inject]
public required DimensionManager DimensionManager { get; init; }
[Inject]
public required ILogger<LogViewer> Logger { get; init; }
[Parameter]
public LogEntries? LogEntries { get; set; } = null!;
protected override void OnParametersSet()
{
if (_logEntries != LogEntries)
{
Logger.LogDebug("Log entries changed.");
_logsChanged = true;
_logEntries = LogEntries;
}
base.OnParametersSet();
}
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (_logsChanged)
{
await JS.InvokeVoidAsync("resetContinuousScrollPosition");
_logsChanged = false;
}
if (firstRender)
{
Logger.LogDebug("Initializing log viewer.");
await JS.InvokeVoidAsync("initializeContinuousScroll");
DimensionManager.OnViewportInformationChanged += OnBrowserResize;
}
}
private void OnBrowserResize(object? o, EventArgs args)
{
InvokeAsync(async () =>
{
await JS.InvokeVoidAsync("resetContinuousScrollPosition");
await JS.InvokeVoidAsync("initializeContinuousScroll");
});
}
private string GetDisplayTimestamp(DateTimeOffset timestamp)
{
var date = _convertTimestampsFromUtc ? TimeProvider.ToLocal(timestamp) : timestamp.DateTime;
return date.ToString(KnownFormats.ConsoleLogsUITimestampFormat, CultureInfo.InvariantCulture);
}
public ValueTask DisposeAsync()
{
Logger.LogDebug("Disposing log viewer.");
DimensionManager.OnViewportInformationChanged -= OnBrowserResize;
return ValueTask.CompletedTask;
}
}
|