using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Linq; using System.Threading.Tasks; using ClaudeDo.Data.Models; using ClaudeDo.Ui.Localization; using ClaudeDo.Ui.Services; using CommunityToolkit.Mvvm.ComponentModel; using CommunityToolkit.Mvvm.Input; namespace ClaudeDo.Ui.ViewModels.Modals; /// /// Log Visualizer overlay — shows the worker's last 30 min of log records (all levels), /// fetched once on open via with a manual /// Refresh and a "warnings & errors only" filter. /// public sealed partial class LogVisualizerViewModel : ViewModelBase { private readonly IWorkerClient _worker; private IReadOnlyList _all = Array.Empty(); public ObservableCollection Rows { get; } = new(); [ObservableProperty] private bool _warnErrorOnly; [ObservableProperty] private string _statusText = ""; public Action? CloseAction { get; set; } public LogVisualizerViewModel(IWorkerClient worker) => _worker = worker; [RelayCommand] public async Task RefreshAsync() { _all = await _worker.GetRecentLogsAsync(); Apply(); } partial void OnWarnErrorOnlyChanged(bool value) => Apply(); private void Apply() { Rows.Clear(); IEnumerable items = WarnErrorOnly ? _all.Where(e => e.Level is WorkerLogLevel.Warn or WorkerLogLevel.Error) : _all; foreach (var e in items) Rows.Add(new LogVisualizerRow(e.TimestampUtc.ToLocalTime().ToString("HH:mm:ss"), e.Message, e.Level)); StatusText = Rows.Count == 0 ? Loc.T("modals.logVisualizer.empty") : Loc.T("modals.logVisualizer.count", Rows.Count); } [RelayCommand] private void Close() => CloseAction?.Invoke(); } public sealed record LogVisualizerRow(string Time, string Message, WorkerLogLevel Level);