feat(central-ui): Flow Debugger status strip log counts + inline-truncation notes; detail cross-step selection
This commit is contained in:
+43
-2
@@ -183,6 +183,44 @@ public partial class FlowDebugger : ComponentBase, IDisposable
|
||||
|
||||
private int PendingCount => _graph?.Steps.Count(s => s.Outcome == FlowStepOutcome.Pending) ?? 0;
|
||||
|
||||
/// <summary>
|
||||
/// Step logs (design 2026-09-09 D5): the run's log lines summed by level over every step that
|
||||
/// carries any. <c>error</c> and <c>warn</c> are counted by name (ordinal, case-insensitive —
|
||||
/// the level rides the audit row as free text); everything else, <c>debug</c> included, is
|
||||
/// "info", so the three counts always add up to <c>Total</c>. Lines the builder could not place
|
||||
/// on a step are NOT here — they are reported separately as
|
||||
/// <see cref="FlowGraph.UnattachedLogLines"/>.
|
||||
/// </summary>
|
||||
internal static (int Errors, int Warnings, int Info, int Total) CountLogs(FlowGraph? graph)
|
||||
{
|
||||
if (graph is null)
|
||||
return (0, 0, 0, 0);
|
||||
|
||||
var errors = 0;
|
||||
var warnings = 0;
|
||||
var info = 0;
|
||||
foreach (var line in graph.Steps.SelectMany(s => s.Logs ?? []))
|
||||
{
|
||||
if (string.Equals(line.Level, "error", StringComparison.OrdinalIgnoreCase)) errors++;
|
||||
else if (string.Equals(line.Level, "warn", StringComparison.OrdinalIgnoreCase)) warnings++;
|
||||
else info++;
|
||||
}
|
||||
|
||||
return (errors, warnings, info, errors + warnings + info);
|
||||
}
|
||||
|
||||
private (int Errors, int Warnings, int Info, int Total) LogCounts => CountLogs(_graph);
|
||||
|
||||
/// <summary>Status-strip text for <see cref="LogCounts"/>.</summary>
|
||||
private string LogSummary
|
||||
{
|
||||
get
|
||||
{
|
||||
var counts = LogCounts;
|
||||
return $"{counts.Errors} errors · {counts.Warnings} warnings · {counts.Info} info";
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Pending outbound work, or an acted-on node that is still Parked, keeps the refresh loop alive.</summary>
|
||||
private bool ShouldKeepPolling =>
|
||||
PendingCount > 0
|
||||
@@ -647,8 +685,11 @@ public partial class FlowDebugger : ComponentBase, IDisposable
|
||||
var selectedId = _selected?.EventId;
|
||||
var merged = MergeEvents(_raw.Events, outcome.Raw?.Events);
|
||||
var truncated = _raw.Truncated || outcome.Raw?.Truncated == true;
|
||||
_raw = _raw with { Events = merged, Truncated = truncated };
|
||||
_graph = FlowGraphBuilder.Build(merged, truncated);
|
||||
// Truncation is sticky across a refresh, exactly as the event-list flag is: the Live run's
|
||||
// inline copy stays the incomplete one whatever the re-read brought back (D7).
|
||||
var logsTruncated = _raw.LogsTruncated || outcome.Raw?.LogsTruncated == true;
|
||||
_raw = _raw with { Events = merged, Truncated = truncated, LogsTruncated = logsTruncated };
|
||||
_graph = FlowGraphBuilder.Build(merged, truncated, logsTruncated);
|
||||
_selected = selectedId is { } id ? _graph.Steps.FirstOrDefault(s => s.EventId == id) ?? _selected : _selected;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user