Files
I150/srcs/RobotNet10/Components/RobotNet10.ScriptEditor/Dialogs/MissionLogDialog.razor
2026-07-03 16:37:12 +07:00

127 lines
4.3 KiB
Plaintext

@using MudBlazor
@using RobotNet10.ScriptEditor.Clients
@using RobotNet10.ScriptEngine.Shared
@using RobotNet10.Shared
@implements IAsyncDisposable
<MudDialog>
<TitleContent>
<MudText Typo="Typo.h6">Mission Log: @MissionName</MudText>
</TitleContent>
<DialogContent>
<MudPaper Elevation="0" Class="pa-4" Style="max-height: 60vh; overflow-y: auto; font-family: 'Courier New', monospace; font-size: 0.875rem;">
@if (string.IsNullOrWhiteSpace(_logText))
{
<MudText Typo="Typo.body2" Color="Color.Default">No logs available</MudText>
}
else
{
<MudText Typo="Typo.body2" Style="white-space: pre-wrap; word-break: break-word;">@_logText</MudText>
}
</MudPaper>
</DialogContent>
<DialogActions>
<MudButton Variant="Variant.Text" OnClick="Close">Close</MudButton>
</DialogActions>
</MudDialog>
@code {
[CascadingParameter] IMudDialogInstance Dialog { get; set; } = null!;
[Parameter] public Guid MissionId { get; set; }
[Parameter] public string MissionName { get; set; } = "";
[Parameter] public ScriptMissionState State { get; set; }
[Parameter] public string? InitialLog { get; set; }
[Inject] private InstanceMissionHubClient InstanceMissionClient { get; set; } = null!;
[Inject] private ConsoleHubClient ConsoleClient { get; set; } = null!;
private string _logText = "";
private bool _isListening = false;
private bool _isStopped => State == ScriptMissionState.Completed ||
State == ScriptMissionState.Canceled ||
State == ScriptMissionState.Error;
protected override async Task OnInitializedAsync()
{
await base.OnInitializedAsync();
// Load initial log
if (!string.IsNullOrWhiteSpace(InitialLog))
{
_logText = InitialLog;
}
else
{
try
{
var log = await InstanceMissionClient.GetInstanceMissionLogAsync(MissionId);
if (!string.IsNullOrWhiteSpace(log))
{
_logText = log;
}
}
catch (Exception ex)
{
_logText = $"Error loading log: {ex.Message}";
}
}
// Start listening to realtime logs if mission is not stopped
if (!_isStopped)
{
_isListening = true;
// Subscribe to log events with proper level formatting
ConsoleClient.ErrorReceived += OnErrorReceived;
ConsoleClient.InfoReceived += OnInfoReceived;
ConsoleClient.WarningReceived += OnWarningReceived;
await ConsoleClient.StartAsync();
await ConsoleClient.RegisterMissionAsync(MissionId);
}
}
private void OnErrorReceived(string message)
{
var timestamp = DateTime.UtcNow.ToString("yyyy-MM-ddTHH:mm:ss.fffZ");
_logText += $"[ERROR] {timestamp} | {message}{Environment.NewLine}";
InvokeAsync(StateHasChanged);
}
private void OnInfoReceived(string message)
{
var timestamp = DateTime.UtcNow.ToString("yyyy-MM-ddTHH:mm:ss.fffZ");
_logText += $"[INFO] {timestamp} | {message}{Environment.NewLine}";
InvokeAsync(StateHasChanged);
}
private void OnWarningReceived(string message)
{
var timestamp = DateTime.UtcNow.ToString("yyyy-MM-ddTHH:mm:ss.fffZ");
_logText += $"[WARN] {timestamp} | {message}{Environment.NewLine}";
InvokeAsync(StateHasChanged);
}
private void Close()
{
Dialog.Close();
}
public async ValueTask DisposeAsync()
{
if (_isListening && ConsoleClient.IsConnected)
{
try
{
ConsoleClient.ErrorReceived -= OnErrorReceived;
ConsoleClient.InfoReceived -= OnInfoReceived;
ConsoleClient.WarningReceived -= OnWarningReceived;
await ConsoleClient.UnregisterMissionAsync(MissionId);
await ConsoleClient.StopAsync();
}
catch { /* Ignore */ }
}
}
}