This is an automated email from the ASF dual-hosted git repository. davsclaus pushed a commit to branch feature/CAMEL-23672-tui-diagram in repository https://gitbox.apache.org/repos/asf/camel.git
commit decec6c8e1587864e5d9df4143d131644e39c9f0 Author: Claus Ibsen <[email protected]> AuthorDate: Thu Jun 4 09:52:18 2026 +0200 CAMEL-23672: camel-tui - Route diagram external styling and description mode Co-Authored-By: Claude Opus 4.6 <[email protected]> Signed-off-by: Claus Ibsen <[email protected]> --- .../jbang/core/commands/tui/DiagramSupport.java | 24 ++++++++- .../dsl/jbang/core/commands/tui/DiagramTab.java | 4 +- .../commands/tui/diagram/RouteDiagramWidget.java | 62 +++++++++++++++++++--- 3 files changed, 80 insertions(+), 10 deletions(-) diff --git a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/DiagramSupport.java b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/DiagramSupport.java index 0b9d6635a401..5a8b3b7e4913 100644 --- a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/DiagramSupport.java +++ b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/DiagramSupport.java @@ -858,6 +858,23 @@ class DiagramSupport { return endpoints; } + private Map<String, String> computeRouteDescriptions() { + Map<String, String> descriptions = new HashMap<>(); + for (var entry : routeLayouts.entrySet()) { + var lr = entry.getValue(); + for (var node : lr.nodes) { + if ("route".equals(node.type) && node.treeNode != null) { + String desc = node.treeNode.info.description; + if (desc != null && !desc.isBlank()) { + descriptions.put(entry.getKey(), desc); + } + break; + } + } + } + return descriptions; + } + private static String findFromUri(RouteDiagramLayoutEngine.LayoutRoute lr) { for (var node : lr.nodes) { if ("from".equals(node.type) && node.treeNode != null) { @@ -879,9 +896,11 @@ class DiagramSupport { Rect inner = block.inner(area); int nw = RouteDiagramLayoutEngine.DEFAULT_BOX_WIDTH * RouteDiagramLayoutEngine.SCALE; Map<String, String> linkable = computeLinkableEndpoints(currentRouteId); + Map<String, String> routeDescs = showDescription ? computeRouteDescriptions() : Collections.emptyMap(); var widget = new org.apache.camel.dsl.jbang.core.commands.tui.diagram.RouteDiagramWidget( - routeLayout, nw, selectedEipNodeIndex, scrollX, scrollY, metrics, linkable); + routeLayout, nw, selectedEipNodeIndex, scrollX, scrollY, metrics, linkable, + showDescription, routeDescs); int totalRows = widget.getTotalRows(); int totalCols = widget.getTotalCols(); @@ -896,7 +915,8 @@ class DiagramSupport { scrollX = Math.min(scrollX, maxHScroll); var finalWidget = new org.apache.camel.dsl.jbang.core.commands.tui.diagram.RouteDiagramWidget( - routeLayout, nw, selectedEipNodeIndex, scrollX, scrollY, metrics, linkable); + routeLayout, nw, selectedEipNodeIndex, scrollX, scrollY, metrics, linkable, + showDescription, routeDescs); List<Rect> vChunks = Layout.vertical() .constraints(Constraint.fill(), Constraint.length(1)) diff --git a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/DiagramTab.java b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/DiagramTab.java index f48e7854eabe..c293f444f309 100644 --- a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/DiagramTab.java +++ b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/DiagramTab.java @@ -572,13 +572,13 @@ class DiagramTab implements MonitorTab { long ago = now - stat.lastCompletedExchangeTimestamp; lines.add(Line.from( Span.styled(" success: ", Style.EMPTY.dim()), - Span.raw(TimeUtils.printDuration(ago, true)))); + Span.raw(TimeUtils.printDuration(ago, false)))); } if (stat.lastFailedExchangeTimestamp > 0) { long ago = now - stat.lastFailedExchangeTimestamp; lines.add(Line.from( Span.styled(" fail: ", Style.EMPTY.dim()), - Span.styled(TimeUtils.printDuration(ago, true), + Span.styled(TimeUtils.printDuration(ago, false), Style.EMPTY.fg(Color.LIGHT_RED)))); } } diff --git a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/diagram/RouteDiagramWidget.java b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/diagram/RouteDiagramWidget.java index 4b616eb51af8..ae2adf1d1c4a 100644 --- a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/diagram/RouteDiagramWidget.java +++ b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/diagram/RouteDiagramWidget.java @@ -58,6 +58,10 @@ public class RouteDiagramWidget implements Widget { private final boolean showMetrics; private final Map<String, String> linkableEndpoints; + private final boolean showDescription; + private final Map<String, String> routeDescriptions; + private final String currentRouteLabel; + private final List<EipNodeBox> nodeBoxes = new ArrayList<>(); public record EipNodeBox(String nodeId, String type, int startRow, int endRow, int startCol, int endCol, @@ -69,13 +73,22 @@ public class RouteDiagramWidget implements Widget { int selectedNodeIndex, int scrollX, int scrollY, boolean showMetrics) { this(layoutRoute, nodeWidth, selectedNodeIndex, scrollX, scrollY, showMetrics, - Collections.emptyMap()); + Collections.emptyMap(), false, Collections.emptyMap()); } public RouteDiagramWidget( LayoutRoute layoutRoute, int nodeWidth, int selectedNodeIndex, int scrollX, int scrollY, boolean showMetrics, Map<String, String> linkableEndpoints) { + this(layoutRoute, nodeWidth, selectedNodeIndex, scrollX, scrollY, showMetrics, + linkableEndpoints, false, Collections.emptyMap()); + } + + public RouteDiagramWidget( + LayoutRoute layoutRoute, int nodeWidth, + int selectedNodeIndex, int scrollX, int scrollY, + boolean showMetrics, Map<String, String> linkableEndpoints, + boolean showDescription, Map<String, String> routeDescriptions) { this.layoutRoute = layoutRoute; this.nodeWidth = nodeWidth; this.boxWidth = Math.max(MIN_BOX_WIDTH, nodeWidth / X_DIVISOR); @@ -84,6 +97,20 @@ public class RouteDiagramWidget implements Widget { this.scrollY = scrollY; this.showMetrics = showMetrics; this.linkableEndpoints = linkableEndpoints; + this.showDescription = showDescription; + this.routeDescriptions = routeDescriptions; + if (showDescription) { + String desc = null; + for (LayoutNode ln : layoutRoute.nodes) { + if ("route".equals(ln.type) && ln.treeNode != null) { + desc = ln.treeNode.info.description; + break; + } + } + this.currentRouteLabel = (desc != null && !desc.isBlank()) ? desc : layoutRoute.routeId; + } else { + this.currentRouteLabel = null; + } } public List<EipNodeBox> getNodeBoxes() { @@ -208,9 +235,10 @@ public class RouteDiagramWidget implements Widget { StatInfo stat = resolveStatInfo(to); long total = stat != null ? stat.exchangesTotal : 0; - boolean dashed = (showMetrics && total == 0) || isExternalEndpoint(to); + boolean external = isExternalEndpoint(to); + boolean dashed = (showMetrics && total == 0) || external; - drawArrowPath(buffer, area, fromCx, fromBottom, toCx, toTop, dashed); + drawArrowPath(buffer, area, fromCx, fromBottom, toCx, toTop, dashed, external); drawCounters(buffer, area, toCx, toTop, stat); } @@ -224,18 +252,27 @@ public class RouteDiagramWidget implements Widget { long total = stat != null ? stat.exchangesTotal : 0; boolean dashed = showMetrics && total == 0; - drawArrowPath(buffer, area, fromCx, fromRow, toCx, toTop, dashed); + drawArrowPath(buffer, area, fromCx, fromRow, toCx, toTop, dashed, false); drawCounters(buffer, area, toCx, toTop, stat); } - private void drawArrowPath(Buffer buffer, Rect area, int fromCx, int fromRow, int toCx, int toRow, boolean dashed) { + private void drawArrowPath( + Buffer buffer, Rect area, int fromCx, int fromRow, int toCx, int toRow, + boolean dashed, boolean external) { if (fromRow >= toRow) { return; } char vChar = dashed ? DASH_V : V; char hChar = dashed ? DASH_H : H; - Style edgeStyle = dashed ? Style.EMPTY.fg(Color.DARK_GRAY) : Style.EMPTY.fg(Color.GRAY); + Style edgeStyle; + if (external) { + edgeStyle = Style.EMPTY.fg(EXTERNAL_COLOR); + } else if (dashed) { + edgeStyle = Style.EMPTY.fg(Color.DARK_GRAY); + } else { + edgeStyle = Style.EMPTY.fg(Color.GRAY); + } if (fromCx == toCx) { for (int r = fromRow; r < toRow - 1; r++) { @@ -338,6 +375,19 @@ public class RouteDiagramWidget implements Widget { private List<String> rewrapText(LayoutNode node, int maxWidth) { String label = String.join("", node.wrappedLines); + if (showDescription) { + if ("from".equals(node.type) && currentRouteLabel != null) { + label = currentRouteLabel; + } else { + String linkedRouteId = findLinkedRouteId(node); + if (linkedRouteId != null) { + String desc = routeDescriptions.get(linkedRouteId); + if (desc != null && !desc.isBlank()) { + label = desc; + } + } + } + } return wrapText(label, maxWidth); }
