This is an automated email from the ASF dual-hosted git repository. davsclaus pushed a commit to branch camel-23420-tui-text-diagram in repository https://gitbox.apache.org/repos/asf/camel.git
commit bd647c505de93eee598b147d52933ae51dbbabb8 Author: Claus Ibsen <[email protected]> AuthorDate: Wed May 13 13:44:45 2026 +0200 CAMEL-23420: Show live route info header in fullscreen text diagram Co-Authored-By: Claude Opus 4.7 <[email protected]> --- .../dsl/jbang/core/commands/tui/CamelMonitor.java | 65 +++++++++++++++++++++- 1 file changed, 64 insertions(+), 1 deletion(-) diff --git a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/CamelMonitor.java b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/CamelMonitor.java index 2d34377cee4f..4dbd99590353 100644 --- a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/CamelMonitor.java +++ b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/CamelMonitor.java @@ -713,7 +713,12 @@ public class CamelMonitor extends CamelCommand { // Fullscreen text diagram mode if (showDiagram && diagramTextMode && !diagramLines.isEmpty()) { - renderDiagram(frame, area); + // Split: route info header (4 rows) + diagram (fill) + List<Rect> fullChunks = Layout.vertical() + .constraints(Constraint.length(4), Constraint.fill()) + .split(area); + renderRouteHeader(frame, fullChunks.get(0), info); + renderDiagram(frame, fullChunks.get(1)); return; } @@ -865,6 +870,64 @@ public class CamelMonitor extends CamelCommand { frame.renderStatefulWidget(table, area, new TableState()); } + private void renderRouteHeader(Frame frame, Rect area, IntegrationInfo info) { + RouteInfo route = null; + if (diagramRouteId != null) { + for (RouteInfo r : info.routes) { + if (diagramRouteId.equals(r.routeId)) { + route = r; + break; + } + } + } + + List<Row> rows = new ArrayList<>(); + if (route != null) { + Style stateStyle = "Started".equals(route.state) + ? Style.create().fg(Color.GREEN) + : Style.create().fg(Color.RED); + Style failStyle = route.failed > 0 + ? Style.create().fg(Color.RED).bold() + : Style.create(); + rows.add(Row.from( + Cell.from(Span.styled(route.routeId != null ? route.routeId : "", Style.create().fg(Color.CYAN))), + Cell.from(route.from != null ? route.from : ""), + Cell.from(Span.styled(route.state != null ? route.state : "", stateStyle)), + Cell.from(route.uptime != null ? route.uptime : ""), + Cell.from(route.throughput != null ? route.throughput : ""), + Cell.from(String.valueOf(route.total)), + Cell.from(Span.styled(String.valueOf(route.failed), failStyle)), + Cell.from(route.meanTime + "/" + route.maxTime))); + } + + Table table = Table.builder() + .rows(rows) + .header(Row.from( + Cell.from(Span.styled("ROUTE", Style.create().bold())), + Cell.from(Span.styled("FROM", Style.create().bold())), + Cell.from(Span.styled("STATE", Style.create().bold())), + Cell.from(Span.styled("UPTIME", Style.create().bold())), + Cell.from(Span.styled("THRUPUT", Style.create().bold())), + Cell.from(Span.styled("TOTAL", Style.create().bold())), + Cell.from(Span.styled("FAILED", Style.create().bold())), + Cell.from(Span.styled("MEAN/MAX", Style.create().bold())))) + .widths( + Constraint.length(12), + Constraint.fill(), + Constraint.length(10), + Constraint.length(8), + Constraint.length(10), + Constraint.length(8), + Constraint.length(8), + Constraint.length(12)) + .highlightStyle(Style.create().fg(Color.WHITE).bold().onBlue()) + .block(Block.builder().borderType(BorderType.ROUNDED) + .title(" Route [" + info.name + "] ").build()) + .build(); + + frame.renderStatefulWidget(table, area, new TableState()); + } + private void renderDiagram(Frame frame, Rect area) { Block block = Block.builder() .borderType(BorderType.ROUNDED)
