@using MudBlazor @using RobotNet10.ScriptEditor.Clients @using RobotNet10.ScriptEngine.Shared @using RobotNet10.Shared @implements IAsyncDisposable Mission Log: @MissionName @if (string.IsNullOrWhiteSpace(_logText)) { No logs available } else { @_logText } Close @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 */ } } } }