This is an automated email from the ASF dual-hosted git repository.

davsclaus pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel.git


The following commit(s) were added to refs/heads/main by this push:
     new 36026da34c56 CAMEL-23519: Add notification badges to TUI tab labels 
(#23238)
36026da34c56 is described below

commit 36026da34c5635c4c3d9891c4d70108575513391
Author: Claus Ibsen <[email protected]>
AuthorDate: Fri May 15 16:39:40 2026 +0200

    CAMEL-23519: Add notification badges to TUI tab labels (#23238)
    
    Show (n) notification counts on each tab label in yellow bold:
    - Overview: active integration count
    - Routes, Endpoints, Health: from selected integration data
    - Log: filtered log entry count
    - History: history entry count (loaded on integration select)
    - Trace: (*) indicator when trace data exists
    
    Counts are 0 (no badge) when no integration is selected.
    Badges update in real-time on each render tick.
    
    Also separate Escape from Quit: Escape navigates back and
    unselects integration, q/Ctrl+c quits the TUI.
    
    Signed-off-by: Claus Ibsen <[email protected]>
    Co-authored-by: Claude Opus 4.6 (1M context) <[email protected]>
---
 .../dsl/jbang/core/commands/tui/CamelMonitor.java  | 59 ++++++++++++++++++----
 1 file changed, 49 insertions(+), 10 deletions(-)

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 fe577c5def47..5f9b9e853a55 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
@@ -261,8 +261,8 @@ public class CamelMonitor extends CamelCommand {
 
     private boolean handleEvent(Event event, TuiRunner runner) {
         if (event instanceof KeyEvent ke) {
-            // Global keys
-            if (ke.isQuit() || ke.isCharIgnoreCase('q') || ke.isCancel()) {
+            // Escape: navigate back
+            if (ke.isCancel()) {
                 if (showDiagram) {
                     showDiagram = false;
                     diagramImageData = null;
@@ -275,12 +275,19 @@ public class CamelMonitor extends CamelCommand {
                     traceDetailScroll = 0;
                     return true;
                 }
-                // If in a detail tab, go back to overview first
                 if (tabsState.selected() != TAB_OVERVIEW) {
                     tabsState.select(TAB_OVERVIEW);
                     selectedPid = null;
                     return true;
                 }
+                if (selectedPid != null) {
+                    selectedPid = null;
+                    return true;
+                }
+                return true;
+            }
+            // Quit: q or Ctrl+c
+            if (ke.isCharIgnoreCase('q') || ke.isCtrlC()) {
                 runner.quit();
                 return true;
             }
@@ -639,6 +646,13 @@ public class CamelMonitor extends CamelCommand {
         } else if (infos.size() == 1) {
             selectedPid = infos.get(0).pid;
         }
+        if (selectedPid != null) {
+            List<Long> pids = List.of(Long.parseLong(selectedPid));
+            refreshHistoryData(pids);
+            traceFilePositions.clear();
+            traces.set(Collections.emptyList());
+            refreshTraceData(pids);
+        }
     }
 
     private void navigateUp() {
@@ -748,15 +762,30 @@ public class CamelMonitor extends CamelCommand {
     }
 
     private void renderTabs(Frame frame, Rect area) {
+        // Compute notification counts (0 if no integration selected)
+        List<IntegrationInfo> infos = data.get();
+        long activeCount = infos.stream().filter(i -> !i.vanishing).count();
+        IntegrationInfo sel = findSelectedIntegration();
+        boolean hasSelection = selectedPid != null && sel != null;
+        int routeCount = hasSelection ? sel.routes.size() : 0;
+        int logCount = hasSelection ? filteredLogEntries.size() : 0;
+        int endpointCount = hasSelection ? sel.endpoints.size() : 0;
+        int healthCount = hasSelection ? sel.healthChecks.size() : 0;
+        int historyCount = hasSelection ? historyEntries.size() : 0;
+        boolean hasTraces = hasSelection && !traces.get().isEmpty();
+
         Tabs tabs = Tabs.builder()
                 .titles(
-                        " 1 Overview ",
-                        " 2 Routes ",
-                        " 3 Log ",
-                        " 4 Endpoints ",
-                        " 5 Health ",
-                        " 6 History ",
-                        " 7 Trace ")
+                        badge(" 1 Overview ", activeCount),
+                        badge(" 2 Routes ", routeCount),
+                        badge(" 3 Log ", logCount),
+                        badge(" 4 Endpoints ", endpointCount),
+                        badge(" 5 Health ", healthCount),
+                        badge(" 6 History ", historyCount),
+                        hasTraces
+                                ? Line.from(Span.raw(" 7 Trace "), 
Span.styled("(*)", Style.EMPTY.fg(Color.YELLOW).bold()),
+                                        Span.raw(" "))
+                                : Line.from(" 7 Trace "))
                 .highlightStyle(Style.EMPTY.fg(Color.rgb(0xF6, 0x91, 
0x23)).bold())
                 .divider(Span.styled(" | ", Style.EMPTY.dim()))
                 .build();
@@ -2844,6 +2873,16 @@ public class CamelMonitor extends CamelCommand {
         return Cell.from(Span.styled(String.format("%" + width + "s", text), 
style));
     }
 
+    private static Line badge(String label, long count) {
+        if (count > 0) {
+            return Line.from(
+                    Span.raw(label),
+                    Span.styled("(" + count + ")", 
Style.EMPTY.fg(Color.YELLOW).bold()),
+                    Span.raw(" "));
+        }
+        return Line.from(label);
+    }
+
     private static final Style HINT_KEY_STYLE = 
Style.EMPTY.fg(Color.YELLOW).bold();
 
     private static void hint(List<Span> spans, String key, String label) {

Reply via email to