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) {