This is an automated email from the ASF dual-hosted git repository. gnodet pushed a commit to branch improve-mouse-support-in-tui-scrolling-with-wheel in repository https://gitbox.apache.org/repos/asf/camel.git
commit 9208873ac94b4e36ba00f8a5fd6f918f0679d17a Author: Guillaume Nodet <[email protected]> AuthorDate: Wed Jul 1 23:34:02 2026 +0200 chore: apply SOLID principles to TUI class hierarchy - Move static utilities (formatting, hint/hintLast, contains, compareStr) from MonitorContext and AbstractTab to TuiHelper (SRP) - Add default implementations to MonitorTab interface to reduce mandatory overrides (ISP) - MonitorContext is now pure shared mutable state with no static members Co-Authored-By: Claude Opus 4.6 <[email protected]> --- .../dsl/jbang/core/commands/tui/AbstractTab.java | 107 +++++++--- .../jbang/core/commands/tui/AbstractTableTab.java | 12 +- .../dsl/jbang/core/commands/tui/ActionsPopup.java | 6 +- .../dsl/jbang/core/commands/tui/AiLogPopup.java | 4 +- .../camel/dsl/jbang/core/commands/tui/AiPanel.java | 16 +- .../dsl/jbang/core/commands/tui/BeansTab.java | 2 +- .../dsl/jbang/core/commands/tui/BrowseTab.java | 6 +- .../dsl/jbang/core/commands/tui/CamelMonitor.java | 7 +- .../jbang/core/commands/tui/CaptionOverlay.java | 4 +- .../jbang/core/commands/tui/CircuitBreakerTab.java | 8 +- .../dsl/jbang/core/commands/tui/ClasspathTab.java | 2 +- .../jbang/core/commands/tui/ConfigurationTab.java | 2 +- .../dsl/jbang/core/commands/tui/ConsumersTab.java | 2 +- .../core/commands/tui/DataRefreshService.java | 2 +- .../dsl/jbang/core/commands/tui/DataSourceTab.java | 2 +- .../jbang/core/commands/tui/DiagramSupport.java | 3 +- .../dsl/jbang/core/commands/tui/DiagramTab.java | 2 +- .../dsl/jbang/core/commands/tui/DoctorPopup.java | 2 +- .../dsl/jbang/core/commands/tui/EndpointsTab.java | 2 +- .../dsl/jbang/core/commands/tui/ErrorsTab.java | 2 +- .../dsl/jbang/core/commands/tui/FilesBrowser.java | 6 +- .../dsl/jbang/core/commands/tui/HealthTab.java | 4 +- .../jbang/core/commands/tui/HeapHistogramTab.java | 2 +- .../dsl/jbang/core/commands/tui/HelpOverlay.java | 4 +- .../dsl/jbang/core/commands/tui/HistoryTab.java | 19 +- .../camel/dsl/jbang/core/commands/tui/HttpTab.java | 2 +- .../dsl/jbang/core/commands/tui/InflightTab.java | 2 +- .../camel/dsl/jbang/core/commands/tui/LogTab.java | 2 +- .../dsl/jbang/core/commands/tui/McpFacade.java | 6 +- .../dsl/jbang/core/commands/tui/McpLogPopup.java | 4 +- .../dsl/jbang/core/commands/tui/MemoryTab.java | 2 +- .../dsl/jbang/core/commands/tui/MetricsTab.java | 2 +- .../jbang/core/commands/tui/MonitorContext.java | 227 +-------------------- .../dsl/jbang/core/commands/tui/MonitorTab.java | 13 +- .../dsl/jbang/core/commands/tui/OverviewTab.java | 8 +- .../dsl/jbang/core/commands/tui/PopupManager.java | 4 +- .../dsl/jbang/core/commands/tui/ProcessTab.java | 2 +- .../dsl/jbang/core/commands/tui/RoutesTab.java | 10 +- .../jbang/core/commands/tui/RunOptionsForm.java | 4 +- .../jbang/core/commands/tui/SearchHighlighter.java | 4 +- .../jbang/core/commands/tui/SendMessagePopup.java | 6 +- .../dsl/jbang/core/commands/tui/ShellPanel.java | 8 +- .../dsl/jbang/core/commands/tui/SourceViewer.java | 20 +- .../dsl/jbang/core/commands/tui/SpansTab.java | 38 ++-- .../dsl/jbang/core/commands/tui/SqlQueryTab.java | 2 +- .../dsl/jbang/core/commands/tui/SqlTraceTab.java | 2 +- .../dsl/jbang/core/commands/tui/StartupTab.java | 2 +- .../dsl/jbang/core/commands/tui/StopAllPopup.java | 4 +- .../dsl/jbang/core/commands/tui/ThreadsTab.java | 2 +- .../dsl/jbang/core/commands/tui/TuiHelper.java | 152 ++++++++++++++ .../jbang/core/commands/tui/CamelMonitorTest.java | 2 +- .../commands/tui/MonitorContextRenderTest.java | 30 +-- .../core/commands/tui/MonitorContextTest.java | 72 +++---- 53 files changed, 426 insertions(+), 434 deletions(-) diff --git a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/AbstractTab.java b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/AbstractTab.java index e75fbcd0e5f8..81167cc8586c 100644 --- a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/AbstractTab.java +++ b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/AbstractTab.java @@ -16,14 +16,26 @@ */ package org.apache.camel.dsl.jbang.core.commands.tui; +import java.util.ArrayList; import java.util.List; import dev.tamboui.layout.Rect; +import dev.tamboui.style.Color; +import dev.tamboui.style.Style; import dev.tamboui.terminal.Frame; +import dev.tamboui.text.Line; import dev.tamboui.text.Span; +import dev.tamboui.text.Text; import dev.tamboui.tui.event.MouseEvent; +import dev.tamboui.widgets.block.Block; +import dev.tamboui.widgets.block.BorderType; +import dev.tamboui.widgets.block.Borders; +import dev.tamboui.widgets.block.Title; +import dev.tamboui.widgets.paragraph.Paragraph; import dev.tamboui.widgets.scrollbar.Scrollbar; import dev.tamboui.widgets.scrollbar.ScrollbarState; +import dev.tamboui.widgets.table.Cell; +import dev.tamboui.widgets.table.Row; import dev.tamboui.widgets.table.TableState; abstract class AbstractTab implements MonitorTab { @@ -34,23 +46,79 @@ abstract class AbstractTab implements MonitorTab { this.ctx = ctx; } - @Override - public boolean handleEscape() { - return false; + // ---- Rendering helpers ---- + + protected static void renderNoSelection(Frame frame, Rect area) { + List<Line> lines = new ArrayList<>(); + lines.add(Line.from(Span.raw(""))); + for (String row : TuiHelper.SMALL_CAMEL) { + lines.add(Line.from(Span.styled(" " + row, Style.EMPTY.fg(Theme.accent())))); + } + lines.add(Line.from(Span.raw(""))); + List<Span> hintSpans = new ArrayList<>(); + hintSpans.add(Span.raw(" No integration selected. ")); + TuiHelper.hint(hintSpans, "1", "Overview"); + TuiHelper.hint(hintSpans, "?", "Help"); + lines.add(Line.from(hintSpans)); + + frame.renderWidget( + Paragraph.builder() + .text(Text.from(lines)) + .block(Block.builder().borderType(BorderType.ROUNDED).borders(Borders.ALL) + .title(Title.from(Line.from( + Span.styled(" No integration selected ", Theme.title())))) + .build()) + .build(), + area); + } + + // ---- Cell construction helpers ---- + + protected static Cell rightCell(String text, int width) { + return Cell.from(String.format("%" + width + "s", text)); + } + + protected static Cell rightCell(String text, int width, Style style) { + return Cell.from(Span.styled(String.format("%" + width + "s", text), style)); } - @Override - public void navigateUp() { + protected static Cell centerCell(String text, int width) { + int len = text.length(); + int padding = Math.max(0, width - len); + int leftPad = padding / 2; + return Cell.from(" ".repeat(leftPad) + text); } - @Override - public void navigateDown() { + protected static Cell centerCell(String text, int width, Style style) { + int len = text.length(); + int padding = Math.max(0, width - len); + int leftPad = padding / 2; + return Cell.from(Span.styled(" ".repeat(leftPad) + text, style)); } - @Override - public void renderFooter(List<Span> spans) { + protected static Row emptyRow(String message, int columnCount) { + Cell[] cells = new Cell[columnCount]; + cells[0] = Cell.from(Span.styled(message, Style.EMPTY.dim())); + for (int i = 1; i < columnCount; i++) { + cells[i] = Cell.from(""); + } + return Row.from(cells); } + // ---- Sort helpers ---- + + protected static String sortLabel(String label, String column, String currentSort, boolean reversed) { + return currentSort.equals(column) ? label + (reversed ? "▲" : "▼") : label; + } + + protected static Style sortStyle(String column, String currentSort) { + return currentSort.equals(column) + ? Style.EMPTY.fg(Color.YELLOW).bold() + : Style.EMPTY.bold(); + } + + // ---- Mouse / scrollbar helpers ---- + protected static void renderTableScrollbar( Frame frame, Rect tableArea, TableState tableState, ScrollbarState scrollState, int rowCount) { if (tableArea == null || tableState == null || scrollState == null) { @@ -71,25 +139,6 @@ abstract class AbstractTab implements MonitorTab { frame.renderStatefulWidget(Scrollbar.builder().build(), scrollRect, scrollState); } - protected static int compareStr(String a, String b) { - if (a == null && b == null) { - return 0; - } - if (a == null) { - return -1; - } - if (b == null) { - return 1; - } - return a.compareToIgnoreCase(b); - } - - protected static boolean contains(Rect rect, int x, int y) { - return rect != null - && x >= rect.x() && x < rect.x() + rect.width() - && y >= rect.y() && y < rect.y() + rect.height(); - } - protected static boolean handleTableClick(MouseEvent me, Rect tableArea, TableState tableState, int rowCount) { if (tableArea == null || tableState == null || rowCount <= 0) { return false; @@ -97,7 +146,7 @@ abstract class AbstractTab implements MonitorTab { if (!me.isClick()) { return false; } - if (!contains(tableArea, me.x(), me.y())) { + if (!TuiHelper.contains(tableArea, me.x(), me.y())) { return false; } int rowIndex = tableState.offset() + (me.y() - tableArea.y() - 2); diff --git a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/AbstractTableTab.java b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/AbstractTableTab.java index 67fbb68cc7e1..b5ca8016e6a8 100644 --- a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/AbstractTableTab.java +++ b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/AbstractTableTab.java @@ -28,6 +28,8 @@ import dev.tamboui.tui.event.MouseEvent; import dev.tamboui.widgets.scrollbar.ScrollbarState; import dev.tamboui.widgets.table.TableState; +import static org.apache.camel.dsl.jbang.core.commands.tui.TuiHelper.*; + abstract class AbstractTableTab extends AbstractTab { protected final TableState tableState = new TableState(); @@ -114,7 +116,7 @@ abstract class AbstractTableTab extends AbstractTab { public void render(Frame frame, Rect area) { IntegrationInfo info = ctx.findSelectedIntegration(); if (info == null) { - MonitorContext.renderNoSelection(frame, area); + renderNoSelection(frame, area); return; } renderContent(frame, area, info); @@ -122,18 +124,18 @@ abstract class AbstractTableTab extends AbstractTab { @Override public void renderFooter(List<Span> spans) { - MonitorContext.hint(spans, "Esc", "back"); + hint(spans, "Esc", "back"); if (sortColumns != null) { - MonitorContext.hint(spans, "s", "sort"); + hint(spans, "s", "sort"); } } protected String sortLabel(String label, String column) { - return MonitorContext.sortLabel(label, column, sort, sortReversed); + return sortLabel(label, column, sort, sortReversed); } protected Style sortStyle(String column) { - return MonitorContext.sortStyle(column, sort); + return sortStyle(column, sort); } protected void renderScrollbar(Frame frame, int rowCount) { diff --git a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/ActionsPopup.java b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/ActionsPopup.java index 0d4ba025f97f..bf20c5adb32a 100644 --- a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/ActionsPopup.java +++ b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/ActionsPopup.java @@ -64,8 +64,8 @@ import org.apache.camel.util.json.JsonArray; import org.apache.camel.util.json.JsonObject; import org.apache.camel.util.json.Jsoner; -import static org.apache.camel.dsl.jbang.core.commands.tui.MonitorContext.hint; -import static org.apache.camel.dsl.jbang.core.commands.tui.MonitorContext.hintLast; +import static org.apache.camel.dsl.jbang.core.commands.tui.TuiHelper.hint; +import static org.apache.camel.dsl.jbang.core.commands.tui.TuiHelper.hintLast; class ActionsPopup { @@ -1038,7 +1038,7 @@ class ActionsPopup { JsonObject action = new JsonObject(); action.put("action", "readme"); PathUtils.writeTextSafely(action.toJson(), ctx.getActionFile(info.pid)); - JsonObject response = MonitorContext.pollJsonResponse(outputFile, 5000); + JsonObject response = TuiHelper.pollJsonResponse(outputFile, 5000); if (response != null && response.getString("content") != null) { String raw = response.getString("content"); String file = response.getStringOrDefault("file", "README"); diff --git a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/AiLogPopup.java b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/AiLogPopup.java index fad5ae372bfd..97e8d468d2e1 100644 --- a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/AiLogPopup.java +++ b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/AiLogPopup.java @@ -41,8 +41,8 @@ import dev.tamboui.widgets.list.ScrollMode; import dev.tamboui.widgets.paragraph.Paragraph; import org.apache.camel.util.json.Jsoner; -import static org.apache.camel.dsl.jbang.core.commands.tui.MonitorContext.hint; -import static org.apache.camel.dsl.jbang.core.commands.tui.MonitorContext.hintLast; +import static org.apache.camel.dsl.jbang.core.commands.tui.TuiHelper.hint; +import static org.apache.camel.dsl.jbang.core.commands.tui.TuiHelper.hintLast; class AiLogPopup { diff --git a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/AiPanel.java b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/AiPanel.java index 7c9c1256241f..c40c8fad3eab 100644 --- a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/AiPanel.java +++ b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/AiPanel.java @@ -224,7 +224,7 @@ class AiPanel { if (!visible || lastArea == null) { return false; } - if (!AbstractTab.contains(lastArea, me.x(), me.y())) { + if (!TuiHelper.contains(lastArea, me.x(), me.y())) { return false; } if (me.kind() == MouseEventKind.SCROLL_UP) { @@ -642,19 +642,19 @@ class AiPanel { } void renderFooter(List<Span> spans) { - MonitorContext.hint(spans, "F8", "close"); + TuiHelper.hint(spans, "F8", "close"); if (statsView) { - MonitorContext.hint(spans, "Ctrl+U", "chat"); + TuiHelper.hint(spans, "Ctrl+U", "chat"); } else { - MonitorContext.hint(spans, "Ctrl+U", "usage"); + TuiHelper.hint(spans, "Ctrl+U", "usage"); } - MonitorContext.hint(spans, "Shift+F8", "resize (" + anim.cyclePercent() + "%)"); - MonitorContext.hint(spans, "PgUp/Dn", "scroll"); + TuiHelper.hint(spans, "Shift+F8", "resize (" + anim.cyclePercent() + "%)"); + TuiHelper.hint(spans, "PgUp/Dn", "scroll"); if (!statsView) { if (!thinking.get()) { - MonitorContext.hint(spans, "Enter", "send"); + TuiHelper.hint(spans, "Enter", "send"); } else { - MonitorContext.hint(spans, "Ctrl+C", "cancel"); + TuiHelper.hint(spans, "Ctrl+C", "cancel"); } } } diff --git a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/BeansTab.java b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/BeansTab.java index 0b91b84f1a80..37c2833c8c57 100644 --- a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/BeansTab.java +++ b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/BeansTab.java @@ -45,7 +45,7 @@ import org.apache.camel.dsl.jbang.core.common.PathUtils; import org.apache.camel.util.json.JsonArray; import org.apache.camel.util.json.JsonObject; -import static org.apache.camel.dsl.jbang.core.commands.tui.MonitorContext.*; +import static org.apache.camel.dsl.jbang.core.commands.tui.TuiHelper.*; class BeansTab extends AbstractTableTab { diff --git a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/BrowseTab.java b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/BrowseTab.java index bde9b7a024da..b0aedb6f2d15 100644 --- a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/BrowseTab.java +++ b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/BrowseTab.java @@ -54,7 +54,7 @@ import org.apache.camel.dsl.jbang.core.common.PathUtils; import org.apache.camel.util.json.JsonArray; import org.apache.camel.util.json.JsonObject; -import static org.apache.camel.dsl.jbang.core.commands.tui.MonitorContext.*; +import static org.apache.camel.dsl.jbang.core.commands.tui.TuiHelper.*; class BrowseTab extends AbstractTab { @@ -515,11 +515,11 @@ class BrowseTab extends AbstractTab { } private String sortLabel(String label, String column) { - return MonitorContext.sortLabel(label, column, sort, sortReversed); + return sortLabel(label, column, sort, sortReversed); } private Style sortStyle(String column) { - return MonitorContext.sortStyle(column, sort); + return sortStyle(column, sort); } private static String formatTimestamp(long ts) { 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 0bfbf251c13d..4241b9652446 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 @@ -64,8 +64,9 @@ import picocli.CommandLine; import picocli.CommandLine.Command; import sun.misc.Signal; -import static org.apache.camel.dsl.jbang.core.commands.tui.MonitorContext.*; import static org.apache.camel.dsl.jbang.core.commands.tui.TabRegistry.*; +import static org.apache.camel.dsl.jbang.core.commands.tui.TuiHelper.*; +import static org.apache.camel.dsl.jbang.core.commands.tui.TuiHelper.hint; @Command(name = "monitor", description = "Live dashboard for monitoring Camel integrations", @@ -773,7 +774,7 @@ public class CamelMonitor extends CamelCommand { // Tab bar clicks: detect which tab was clicked and switch to it if (me.isClick() && lastTabsArea != null && lastTabLabels != null) { int tabsY = lastTabsArea.height() >= 2 ? lastTabsArea.y() + 1 : lastTabsArea.y(); - if (me.y() == tabsY && AbstractTab.contains(lastTabsArea, me.x(), me.y())) { + if (me.y() == tabsY && TuiHelper.contains(lastTabsArea, me.x(), me.y())) { int clickedTab = findClickedTab(me.x() - lastTabsArea.x()); if (clickedTab >= 0) { if (isInfraSelected()) { @@ -789,7 +790,7 @@ public class CamelMonitor extends CamelCommand { } // Mouse events in the content area: delegate to the active tab - if (AbstractTab.contains(lastContentArea, me.x(), me.y())) { + if (TuiHelper.contains(lastContentArea, me.x(), me.y())) { if (popupManager.isMorePopupVisible() || popupManager.isSwitchPopupVisible()) { return popupManager.handleMouseEvent(me, tabRegistry.selectedTabIndex(), TAB_LOG); } diff --git a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/CaptionOverlay.java b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/CaptionOverlay.java index 585658274a3a..e0db9b680868 100644 --- a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/CaptionOverlay.java +++ b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/CaptionOverlay.java @@ -31,8 +31,8 @@ import dev.tamboui.tui.event.KeyEvent; import dev.tamboui.widgets.Clear; import dev.tamboui.widgets.paragraph.Paragraph; -import static org.apache.camel.dsl.jbang.core.commands.tui.MonitorContext.hint; -import static org.apache.camel.dsl.jbang.core.commands.tui.MonitorContext.hintLast; +import static org.apache.camel.dsl.jbang.core.commands.tui.TuiHelper.hint; +import static org.apache.camel.dsl.jbang.core.commands.tui.TuiHelper.hintLast; class CaptionOverlay { diff --git a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/CircuitBreakerTab.java b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/CircuitBreakerTab.java index 258013c47036..07d83f20b18b 100644 --- a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/CircuitBreakerTab.java +++ b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/CircuitBreakerTab.java @@ -42,7 +42,7 @@ import dev.tamboui.widgets.table.Table; import org.apache.camel.util.json.JsonArray; import org.apache.camel.util.json.JsonObject; -import static org.apache.camel.dsl.jbang.core.commands.tui.MonitorContext.*; +import static org.apache.camel.dsl.jbang.core.commands.tui.TuiHelper.*; class CircuitBreakerTab extends AbstractTableTab { @@ -164,9 +164,9 @@ class CircuitBreakerTab extends AbstractTableTab { @Override public void renderFooter(List<Span> spans) { - MonitorContext.hint(spans, "Esc", "back"); - MonitorContext.hint(spans, "↑↓", "navigate"); - MonitorContext.hint(spans, "s", "sort"); + hint(spans, "Esc", "back"); + hint(spans, "↑↓", "navigate"); + hint(spans, "s", "sort"); } private int sortCb(CircuitBreakerInfo a, CircuitBreakerInfo b) { diff --git a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/ClasspathTab.java b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/ClasspathTab.java index 706def8d3a56..b19682610caf 100644 --- a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/ClasspathTab.java +++ b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/ClasspathTab.java @@ -47,7 +47,7 @@ import org.apache.camel.dsl.jbang.core.common.PathUtils; import org.apache.camel.util.json.JsonArray; import org.apache.camel.util.json.JsonObject; -import static org.apache.camel.dsl.jbang.core.commands.tui.MonitorContext.*; +import static org.apache.camel.dsl.jbang.core.commands.tui.TuiHelper.*; class ClasspathTab extends AbstractTab { diff --git a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/ConfigurationTab.java b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/ConfigurationTab.java index 6f4b910b0e02..883aa87c74ed 100644 --- a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/ConfigurationTab.java +++ b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/ConfigurationTab.java @@ -42,7 +42,7 @@ import org.apache.camel.util.FileUtil; import org.apache.camel.util.json.JsonArray; import org.apache.camel.util.json.JsonObject; -import static org.apache.camel.dsl.jbang.core.commands.tui.MonitorContext.*; +import static org.apache.camel.dsl.jbang.core.commands.tui.TuiHelper.*; class ConfigurationTab extends AbstractTab { diff --git a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/ConsumersTab.java b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/ConsumersTab.java index bb48dd5c3638..e454fb50c8b2 100644 --- a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/ConsumersTab.java +++ b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/ConsumersTab.java @@ -36,7 +36,7 @@ import dev.tamboui.widgets.table.Table; import org.apache.camel.util.json.JsonArray; import org.apache.camel.util.json.JsonObject; -import static org.apache.camel.dsl.jbang.core.commands.tui.MonitorContext.*; +import static org.apache.camel.dsl.jbang.core.commands.tui.TuiHelper.*; class ConsumersTab extends AbstractTableTab { diff --git a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/DataRefreshService.java b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/DataRefreshService.java index 6005b5aee136..4d449c991268 100644 --- a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/DataRefreshService.java +++ b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/DataRefreshService.java @@ -575,7 +575,7 @@ class DataRefreshService { PathUtils.writeTextSafely(action.toJson(), actionFile); // Poll for response - JsonObject response = MonitorContext.pollJsonResponse(outputFile, 3000); + JsonObject response = TuiHelper.pollJsonResponse(outputFile, 3000); if (response != null) { Boolean enabled = response.getBoolean("enabled"); if (enabled != null && enabled) { diff --git a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/DataSourceTab.java b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/DataSourceTab.java index 955190fa1b3d..8bee8b5f0417 100644 --- a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/DataSourceTab.java +++ b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/DataSourceTab.java @@ -33,7 +33,7 @@ import dev.tamboui.widgets.table.Table; import org.apache.camel.util.json.JsonArray; import org.apache.camel.util.json.JsonObject; -import static org.apache.camel.dsl.jbang.core.commands.tui.MonitorContext.*; +import static org.apache.camel.dsl.jbang.core.commands.tui.TuiHelper.*; class DataSourceTab extends AbstractTableTab { 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 fa48723a4758..1a710f3c6392 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 @@ -63,7 +63,8 @@ import org.apache.camel.dsl.jbang.core.common.PathUtils; import org.apache.camel.util.json.JsonArray; import org.apache.camel.util.json.JsonObject; -import static org.apache.camel.dsl.jbang.core.commands.tui.MonitorContext.*; +import static org.apache.camel.dsl.jbang.core.commands.tui.TuiHelper.*; +import static org.apache.camel.dsl.jbang.core.commands.tui.TuiHelper.hint; class DiagramSupport { 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 81210eba0ffe..97d7cfb0e380 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 @@ -40,7 +40,7 @@ import org.apache.camel.util.TimeUtils; import org.apache.camel.util.json.JsonArray; import org.apache.camel.util.json.JsonObject; -import static org.apache.camel.dsl.jbang.core.commands.tui.MonitorContext.*; +import static org.apache.camel.dsl.jbang.core.commands.tui.TuiHelper.*; class DiagramTab extends AbstractTab { diff --git a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/DoctorPopup.java b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/DoctorPopup.java index 9382ce867ee4..6678a4298e93 100644 --- a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/DoctorPopup.java +++ b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/DoctorPopup.java @@ -41,7 +41,7 @@ import org.apache.camel.dsl.jbang.core.common.VersionHelper; import org.apache.camel.tooling.maven.MavenDownloaderImpl; import org.apache.camel.tooling.maven.MavenResolutionException; -import static org.apache.camel.dsl.jbang.core.commands.tui.MonitorContext.hintLast; +import static org.apache.camel.dsl.jbang.core.commands.tui.TuiHelper.hintLast; class DoctorPopup { diff --git a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/EndpointsTab.java b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/EndpointsTab.java index 1b39eafcb398..d70facbf5c1b 100644 --- a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/EndpointsTab.java +++ b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/EndpointsTab.java @@ -46,7 +46,7 @@ import dev.tamboui.widgets.table.Table; import org.apache.camel.util.json.JsonArray; import org.apache.camel.util.json.JsonObject; -import static org.apache.camel.dsl.jbang.core.commands.tui.MonitorContext.*; +import static org.apache.camel.dsl.jbang.core.commands.tui.TuiHelper.*; class EndpointsTab extends AbstractTableTab { diff --git a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/ErrorsTab.java b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/ErrorsTab.java index 169be3b50754..31b1279c7ac5 100644 --- a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/ErrorsTab.java +++ b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/ErrorsTab.java @@ -45,7 +45,7 @@ import org.apache.camel.util.json.JsonArray; import org.apache.camel.util.json.JsonObject; import org.apache.camel.util.json.Jsoner; -import static org.apache.camel.dsl.jbang.core.commands.tui.MonitorContext.*; +import static org.apache.camel.dsl.jbang.core.commands.tui.TuiHelper.*; class ErrorsTab extends AbstractTableTab { diff --git a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/FilesBrowser.java b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/FilesBrowser.java index c15922a973aa..8df721a40fc8 100644 --- a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/FilesBrowser.java +++ b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/FilesBrowser.java @@ -263,9 +263,9 @@ class FilesBrowser { if (sourceViewer.isVisible()) { sourceViewer.renderFooter(spans); } else { - MonitorContext.hint(spans, "↑↓", "navigate"); - MonitorContext.hint(spans, "Enter", "open"); - MonitorContext.hint(spans, "Esc", "close"); + TuiHelper.hint(spans, "↑↓", "navigate"); + TuiHelper.hint(spans, "Enter", "open"); + TuiHelper.hint(spans, "Esc", "close"); } } diff --git a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/HealthTab.java b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/HealthTab.java index d413bed5d477..eff82d38c861 100644 --- a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/HealthTab.java +++ b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/HealthTab.java @@ -35,7 +35,7 @@ import dev.tamboui.widgets.table.Table; import org.apache.camel.util.json.JsonArray; import org.apache.camel.util.json.JsonObject; -import static org.apache.camel.dsl.jbang.core.commands.tui.MonitorContext.*; +import static org.apache.camel.dsl.jbang.core.commands.tui.TuiHelper.*; class HealthTab extends AbstractTableTab { @@ -137,7 +137,7 @@ class HealthTab extends AbstractTableTab { @Override public void renderFooter(List<Span> spans) { super.renderFooter(spans); - MonitorContext.hint(spans, "d", "toggle DOWN"); + hint(spans, "d", "toggle DOWN"); } boolean isShowOnlyDown() { diff --git a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/HeapHistogramTab.java b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/HeapHistogramTab.java index 43728ed7a5da..39d25764c0e2 100644 --- a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/HeapHistogramTab.java +++ b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/HeapHistogramTab.java @@ -44,7 +44,7 @@ import org.apache.camel.dsl.jbang.core.common.PathUtils; import org.apache.camel.util.json.JsonArray; import org.apache.camel.util.json.JsonObject; -import static org.apache.camel.dsl.jbang.core.commands.tui.MonitorContext.*; +import static org.apache.camel.dsl.jbang.core.commands.tui.TuiHelper.*; class HeapHistogramTab extends AbstractTableTab { diff --git a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/HelpOverlay.java b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/HelpOverlay.java index c375384e20a7..d1ff39391854 100644 --- a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/HelpOverlay.java +++ b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/HelpOverlay.java @@ -31,8 +31,8 @@ import dev.tamboui.widgets.block.BorderType; import dev.tamboui.widgets.block.Borders; import dev.tamboui.widgets.block.Title; -import static org.apache.camel.dsl.jbang.core.commands.tui.MonitorContext.hint; -import static org.apache.camel.dsl.jbang.core.commands.tui.MonitorContext.hintLast; +import static org.apache.camel.dsl.jbang.core.commands.tui.TuiHelper.hint; +import static org.apache.camel.dsl.jbang.core.commands.tui.TuiHelper.hintLast; class HelpOverlay { diff --git a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/HistoryTab.java b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/HistoryTab.java index 8c1595fba4ff..9bba7575a7f8 100644 --- a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/HistoryTab.java +++ b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/HistoryTab.java @@ -61,7 +61,7 @@ import org.apache.camel.util.json.JsonArray; import org.apache.camel.util.json.JsonObject; import org.apache.camel.util.json.Jsoner; -import static org.apache.camel.dsl.jbang.core.commands.tui.MonitorContext.*; +import static org.apache.camel.dsl.jbang.core.commands.tui.TuiHelper.*; class HistoryTab extends AbstractTab { @@ -1174,9 +1174,9 @@ class HistoryTab extends AbstractTab { default -> Style.EMPTY; }; rows.add(Row.from( - Cell.from(s.timestamp != null ? truncate(s.timestamp, 12) : ""), + Cell.from(s.timestamp != null ? TuiHelper.truncate(s.timestamp, 12) : ""), Cell.from(Span.styled( - s.routeId != null ? truncate(s.routeId, 25) : "", + s.routeId != null ? TuiHelper.truncate(s.routeId, 25) : "", Style.EMPTY.fg(Color.CYAN))), Cell.from(Span.styled(s.status, statusStyle)), rightCell(s.elapsed + "ms", 10), @@ -1235,7 +1235,8 @@ class HistoryTab extends AbstractTab { entry.timestamp, entry.routeId, entry.nodeId, entry.processor, desc, entry.elapsed, changes)); } - String stepTitle = String.format(" Trace [%s] — %d steps ", truncate(traceSelectedExchangeId, 30), steps.size()); + String stepTitle + = String.format(" Trace [%s] — %d steps ", TuiHelper.truncate(traceSelectedExchangeId, 30), steps.size()); lastTraceStepArea = chunks.get(0); detailSplit.setBorderPos(chunks.get(1).y()); frame.renderStatefulWidget( @@ -1857,11 +1858,11 @@ class HistoryTab extends AbstractTab { } private String traceSortLabel(String label, String column) { - return MonitorContext.sortLabel(label, column, traceSort, traceSortReversed); + return sortLabel(label, column, traceSort, traceSortReversed); } private Style traceSortStyle(String column) { - return MonitorContext.sortStyle(column, traceSort); + return sortStyle(column, traceSort); } private static Row buildStepRow( @@ -1882,9 +1883,9 @@ class HistoryTab extends AbstractTab { return Row.from( rightCell(String.valueOf(stepNumber), 3), Cell.from(Span.styled(direction, dirStyle)), - Cell.from(timestamp != null ? truncate(timestamp, 12) : ""), - Cell.from(Span.styled(routeId != null ? truncate(routeId, 25) : "", Style.EMPTY.fg(Color.CYAN))), - Cell.from(indent + (nodeId != null ? truncate(nodeId, 25) : "")), + Cell.from(timestamp != null ? TuiHelper.truncate(timestamp, 12) : ""), + Cell.from(Span.styled(routeId != null ? TuiHelper.truncate(routeId, 25) : "", Style.EMPTY.fg(Color.CYAN))), + Cell.from(indent + (nodeId != null ? TuiHelper.truncate(nodeId, 25) : "")), Cell.from(indent + display), Cell.from(Line.from(changeSpans)), rightCell(elapsedStr, 10)); diff --git a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/HttpTab.java b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/HttpTab.java index 0036599d6651..7bd712ea120f 100644 --- a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/HttpTab.java +++ b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/HttpTab.java @@ -61,7 +61,7 @@ import org.apache.camel.dsl.jbang.core.common.PathUtils; import org.apache.camel.util.json.JsonArray; import org.apache.camel.util.json.JsonObject; -import static org.apache.camel.dsl.jbang.core.commands.tui.MonitorContext.*; +import static org.apache.camel.dsl.jbang.core.commands.tui.TuiHelper.*; class HttpTab extends AbstractTableTab { diff --git a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/InflightTab.java b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/InflightTab.java index d83056e29062..2fdacf4c1db8 100644 --- a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/InflightTab.java +++ b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/InflightTab.java @@ -38,7 +38,7 @@ import org.apache.camel.util.TimeUtils; import org.apache.camel.util.json.JsonArray; import org.apache.camel.util.json.JsonObject; -import static org.apache.camel.dsl.jbang.core.commands.tui.MonitorContext.*; +import static org.apache.camel.dsl.jbang.core.commands.tui.TuiHelper.*; class InflightTab extends AbstractTableTab { diff --git a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/LogTab.java b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/LogTab.java index 266c7cd321c8..a6a697dcb466 100644 --- a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/LogTab.java +++ b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/LogTab.java @@ -57,7 +57,7 @@ import org.apache.camel.dsl.jbang.core.common.CommandLineHelper; import org.apache.camel.util.json.JsonArray; import org.apache.camel.util.json.JsonObject; -import static org.apache.camel.dsl.jbang.core.commands.tui.MonitorContext.*; +import static org.apache.camel.dsl.jbang.core.commands.tui.TuiHelper.*; class LogTab extends AbstractTab { diff --git a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/McpFacade.java b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/McpFacade.java index 674c4a3f0f3e..fa9ba23ec8a3 100644 --- a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/McpFacade.java +++ b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/McpFacade.java @@ -40,7 +40,7 @@ import org.apache.camel.dsl.jbang.core.common.RuntimeHelper; import org.apache.camel.util.json.JsonArray; import org.apache.camel.util.json.JsonObject; -import static org.apache.camel.dsl.jbang.core.commands.tui.MonitorContext.hint; +import static org.apache.camel.dsl.jbang.core.commands.tui.TuiHelper.hint; /** * Facade that exposes monitor state and actions to the MCP server. @@ -451,7 +451,7 @@ class McpFacade { Path actionFile = ctx.getActionFile(pid); PathUtils.writeTextSafely(action.toJson(), actionFile); - JsonObject response = MonitorContext.pollJsonResponse(outputFile, 3000); + JsonObject response = TuiHelper.pollJsonResponse(outputFile, 3000); if (response != null) { PathUtils.deleteFile(outputFile); Boolean enabled = response.getBoolean("enabled"); @@ -676,7 +676,7 @@ class McpFacade { JsonObject action = new JsonObject(); action.put("action", "readme"); PathUtils.writeTextSafely(action.toJson(), ctx.getActionFile(target.pid)); - return MonitorContext.pollJsonResponse(outputFile, 5000); + return TuiHelper.pollJsonResponse(outputFile, 5000); } catch (Exception e) { return null; } diff --git a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/McpLogPopup.java b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/McpLogPopup.java index 91cae818a67e..a2e26e4b1f6c 100644 --- a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/McpLogPopup.java +++ b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/McpLogPopup.java @@ -41,8 +41,8 @@ import dev.tamboui.widgets.list.ScrollMode; import dev.tamboui.widgets.paragraph.Paragraph; import org.apache.camel.util.json.Jsoner; -import static org.apache.camel.dsl.jbang.core.commands.tui.MonitorContext.hint; -import static org.apache.camel.dsl.jbang.core.commands.tui.MonitorContext.hintLast; +import static org.apache.camel.dsl.jbang.core.commands.tui.TuiHelper.hint; +import static org.apache.camel.dsl.jbang.core.commands.tui.TuiHelper.hintLast; class McpLogPopup { diff --git a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/MemoryTab.java b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/MemoryTab.java index ad84abbf9042..e68c23de8117 100644 --- a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/MemoryTab.java +++ b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/MemoryTab.java @@ -42,7 +42,7 @@ import org.apache.camel.dsl.jbang.core.common.PathUtils; import org.apache.camel.util.TimeUtils; import org.apache.camel.util.json.JsonObject; -import static org.apache.camel.dsl.jbang.core.commands.tui.MonitorContext.*; +import static org.apache.camel.dsl.jbang.core.commands.tui.TuiHelper.*; class MemoryTab extends AbstractTab { diff --git a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/MetricsTab.java b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/MetricsTab.java index c971926943d0..231c60e87eb3 100644 --- a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/MetricsTab.java +++ b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/MetricsTab.java @@ -52,7 +52,7 @@ import dev.tamboui.widgets.table.Table; import org.apache.camel.util.json.JsonArray; import org.apache.camel.util.json.JsonObject; -import static org.apache.camel.dsl.jbang.core.commands.tui.MonitorContext.*; +import static org.apache.camel.dsl.jbang.core.commands.tui.TuiHelper.*; class MetricsTab extends AbstractTableTab { diff --git a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/MonitorContext.java b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/MonitorContext.java index 2dfac4cc824e..8446ad605148 100644 --- a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/MonitorContext.java +++ b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/MonitorContext.java @@ -16,46 +16,18 @@ */ package org.apache.camel.dsl.jbang.core.commands.tui; -import java.nio.file.Files; import java.nio.file.Path; -import java.util.ArrayList; import java.util.List; import java.util.concurrent.atomic.AtomicReference; -import dev.tamboui.layout.Rect; -import dev.tamboui.style.Color; -import dev.tamboui.style.Style; -import dev.tamboui.terminal.Frame; -import dev.tamboui.text.Line; -import dev.tamboui.text.Span; -import dev.tamboui.text.Text; import dev.tamboui.tui.TuiRunner; -import dev.tamboui.widgets.block.Block; -import dev.tamboui.widgets.block.BorderType; -import dev.tamboui.widgets.block.Borders; -import dev.tamboui.widgets.block.Title; -import dev.tamboui.widgets.paragraph.Paragraph; -import dev.tamboui.widgets.table.Cell; -import dev.tamboui.widgets.table.Row; import org.apache.camel.dsl.jbang.core.common.CommandLineHelper; -import org.apache.camel.util.json.JsonObject; -import org.apache.camel.util.json.Jsoner; /** - * Shared state and utilities accessible to all {@link MonitorTab} implementations. + * Shared state accessible to all {@link MonitorTab} implementations. */ class MonitorContext { - /** Small flat-orange camel for empty / no-selection states. */ - static final String[] SMALL_CAMEL = { - " ,,__", - "/o. \\___/\\", - "\\__/ \\", - " | | |", - " | | |~", - " (_) (_) (_)", - }; - final AtomicReference<List<IntegrationInfo>> data; final AtomicReference<List<InfraInfo>> infraData; TuiRunner runner; @@ -119,201 +91,4 @@ class MonitorContext { return CommandLineHelper.getCamelDir().resolve(pid + "-trace.json"); } - static JsonObject pollJsonResponse(Path outputFile, long timeout) { - long start = System.currentTimeMillis(); - while (System.currentTimeMillis() - start < timeout) { - try { - Thread.sleep(100); - if (Files.exists(outputFile) && outputFile.toFile().length() > 0) { - String text = Files.readString(outputFile); - return (JsonObject) Jsoner.deserialize(text); - } - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - return null; - } catch (Exception e) { - // ignore - } - } - return null; - } - - static void hint(List<Span> spans, String key, String label) { - spans.add(Span.styled(" " + key + " ", Theme.hintKey())); - spans.add(Span.raw(" " + label + " ")); - } - - static void hintLast(List<Span> spans, String key, String label) { - spans.add(Span.styled(" " + key + " ", Theme.hintKey())); - spans.add(Span.raw(" " + label)); - } - - static void renderNoSelection(Frame frame, Rect area) { - List<Line> lines = new ArrayList<>(); - lines.add(Line.from(Span.raw(""))); - for (String row : SMALL_CAMEL) { - lines.add(Line.from(Span.styled(" " + row, Style.EMPTY.fg(Theme.accent())))); - } - lines.add(Line.from(Span.raw(""))); - List<Span> hintSpans = new ArrayList<>(); - hintSpans.add(Span.raw(" No integration selected. ")); - hint(hintSpans, "1", "Overview"); - hint(hintSpans, "?", "Help"); - lines.add(Line.from(hintSpans)); - - frame.renderWidget( - Paragraph.builder() - .text(Text.from(lines)) - .block(Block.builder().borderType(BorderType.ROUNDED).borders(Borders.ALL) - .title(Title.from(Line.from( - Span.styled(" No integration selected ", Theme.title())))) - .build()) - .build(), - area); - } - - static String truncate(String s, int max) { - return TuiHelper.truncate(s, max); - } - - static Cell rightCell(String text, int width) { - return Cell.from(String.format("%" + width + "s", text)); - } - - static Cell rightCell(String text, int width, Style style) { - return Cell.from(Span.styled(String.format("%" + width + "s", text), style)); - } - - static Cell centerCell(String text, int width) { - int len = text.length(); - int padding = Math.max(0, width - len); - int leftPad = padding / 2; - return Cell.from(" ".repeat(leftPad) + text); - } - - static Cell centerCell(String text, int width, Style style) { - int len = text.length(); - int padding = Math.max(0, width - len); - int leftPad = padding / 2; - return Cell.from(Span.styled(" ".repeat(leftPad) + text, style)); - } - - static Row emptyRow(String message, int columnCount) { - Cell[] cells = new Cell[columnCount]; - cells[0] = Cell.from(Span.styled(message, Style.EMPTY.dim())); - for (int i = 1; i < columnCount; i++) { - cells[i] = Cell.from(""); - } - return Row.from(cells); - } - - static String sortLabel(String label, String column, String currentSort, boolean reversed) { - return currentSort.equals(column) ? label + (reversed ? "▲" : "▼") : label; - } - - static Style sortStyle(String column, String currentSort) { - return currentSort.equals(column) - ? Style.EMPTY.fg(Color.YELLOW).bold() - : Style.EMPTY.bold(); - } - - static String formatSinceLast(IntegrationInfo info) { - return formatSinceLast(info.sinceLastStarted, info.sinceLastCompleted, info.sinceLastFailed); - } - - static String formatSinceLast(String started, String completed, String failed) { - StringBuilder sb = new StringBuilder(); - if (started != null) { - sb.append(started); - } - if (completed != null) { - if (!sb.isEmpty()) { - sb.append('/'); - } - sb.append(completed); - } - if (failed != null) { - if (!sb.isEmpty()) { - sb.append('/'); - } - sb.append(failed); - } - return sb.toString(); - } - - static String formatSinceLastRoute(RouteInfo route) { - return formatSinceLast(route.sinceLastStarted, route.sinceLastCompleted, route.sinceLastFailed); - } - - static String formatLoad(String l1, String l5, String l15) { - String s1 = l1 != null && !"0.00".equals(l1) ? l1 : "0"; - String s5 = l5 != null && !"0.00".equals(l5) ? l5 : "0"; - String s15 = l15 != null && !"0.00".equals(l15) ? l15 : "0"; - return s1 + "/" + s5 + "/" + s15; - } - - static String formatMemory(long used, long max) { - if (used <= 0) { - return ""; - } - String u = formatBytes(used); - if (max > 0) { - return u + "/" + formatBytes(max); - } - return u; - } - - static String formatBytes(long bytes) { - if (bytes < 1024) { - return bytes + "B"; - } - if (bytes < 1024 * 1024) { - return (bytes / 1024) + "K"; - } - return (bytes / (1024 * 1024)) + "M"; - } - - static String formatThreads(int count, int peak) { - if (count <= 0) { - return ""; - } - return count + "/" + peak; - } - - static Style topTimeStyle(long ms) { - if (ms >= 1000) { - return Style.EMPTY.fg(Color.LIGHT_RED).bold(); - } else if (ms >= 100) { - return Style.EMPTY.fg(Color.YELLOW); - } - return Style.EMPTY; - } - - static Style topDeltaStyle(long delta) { - if (delta > 0) { - return Style.EMPTY.fg(Color.LIGHT_RED); - } else if (delta < 0) { - return Style.EMPTY.fg(Color.GREEN); - } - return Style.EMPTY; - } - - static String buildBar(long value, long maxValue, int maxWidth) { - if (value <= 0 || maxValue <= 0) { - return ""; - } - int len = (int) Math.round((double) value / maxValue * maxWidth); - len = Math.max(len > 0 ? 1 : 0, Math.min(len, maxWidth)); - return "█".repeat(len); - } - - static int compareStr(String a, String b) { - if (a == null && b == null) - return 0; - if (a == null) - return 1; - if (b == null) - return -1; - return a.compareToIgnoreCase(b); - } } diff --git a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/MonitorTab.java b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/MonitorTab.java index 226a862e0200..8520d2b5c9d0 100644 --- a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/MonitorTab.java +++ b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/MonitorTab.java @@ -43,15 +43,20 @@ interface MonitorTab { return false; } - boolean handleEscape(); + default boolean handleEscape() { + return false; + } - void navigateUp(); + default void navigateUp() { + } - void navigateDown(); + default void navigateDown() { + } void render(Frame frame, Rect area); - void renderFooter(List<Span> spans); + default void renderFooter(List<Span> spans) { + } default void onTabSelected() { } diff --git a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/OverviewTab.java b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/OverviewTab.java index 4338b9309ce4..af1ea4c72b7f 100644 --- a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/OverviewTab.java +++ b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/OverviewTab.java @@ -51,7 +51,7 @@ import dev.tamboui.widgets.table.TableState; import org.apache.camel.util.json.JsonArray; import org.apache.camel.util.json.JsonObject; -import static org.apache.camel.dsl.jbang.core.commands.tui.MonitorContext.*; +import static org.apache.camel.dsl.jbang.core.commands.tui.TuiHelper.*; import static org.apache.camel.dsl.jbang.core.common.CamelCommandHelper.extractState; class OverviewTab extends AbstractTab { @@ -838,11 +838,11 @@ class OverviewTab extends AbstractTab { } private String sortLabel(String label, String column) { - return MonitorContext.sortLabel(label, column, sort, sortReversed); + return sortLabel(label, column, sort, sortReversed); } private Style sortStyle(String column) { - return MonitorContext.sortStyle(column, sort); + return sortStyle(column, sort); } @Override @@ -967,7 +967,7 @@ class OverviewTab extends AbstractTab { private void renderEmptyState(Frame frame, Rect area) { List<Line> lines = new ArrayList<>(); lines.add(Line.from(Span.raw(""))); - for (String row : MonitorContext.SMALL_CAMEL) { + for (String row : TuiHelper.SMALL_CAMEL) { lines.add(Line.from(Span.styled(" " + row, Style.EMPTY.fg(Theme.accent()).bold()))); } lines.add(Line.from(Span.styled(" No Active Camel Integrations Found", Theme.title()))); diff --git a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/PopupManager.java b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/PopupManager.java index 345a603954db..1ecfd2809d5d 100644 --- a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/PopupManager.java +++ b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/PopupManager.java @@ -258,7 +258,7 @@ class PopupManager { if (lastMorePopupRect == null) { return false; } - boolean inside = AbstractTab.contains(lastMorePopupRect, me.x(), me.y()); + boolean inside = TuiHelper.contains(lastMorePopupRect, me.x(), me.y()); // Click outside the popup closes it if (me.isClick() && !inside) { @@ -299,7 +299,7 @@ class PopupManager { return false; } List<IntegrationInfo> switchList = nonVanishingIntegrationsSupplier.get(); - boolean inside = AbstractTab.contains(lastSwitchPopupRect, me.x(), me.y()); + boolean inside = TuiHelper.contains(lastSwitchPopupRect, me.x(), me.y()); if (me.isClick() && !inside) { showSwitchPopup = false; diff --git a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/ProcessTab.java b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/ProcessTab.java index 22a438c260bf..a3e0827c6a70 100644 --- a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/ProcessTab.java +++ b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/ProcessTab.java @@ -40,7 +40,7 @@ import dev.tamboui.widgets.scrollbar.Scrollbar; import dev.tamboui.widgets.scrollbar.ScrollbarState; import org.apache.camel.util.json.JsonObject; -import static org.apache.camel.dsl.jbang.core.commands.tui.MonitorContext.*; +import static org.apache.camel.dsl.jbang.core.commands.tui.TuiHelper.*; class ProcessTab extends AbstractTab { diff --git a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/RoutesTab.java b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/RoutesTab.java index 6bdf283beec9..698fedbaf022 100644 --- a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/RoutesTab.java +++ b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/RoutesTab.java @@ -48,7 +48,7 @@ import org.apache.camel.util.TimeUtils; import org.apache.camel.util.json.JsonArray; import org.apache.camel.util.json.JsonObject; -import static org.apache.camel.dsl.jbang.core.commands.tui.MonitorContext.*; +import static org.apache.camel.dsl.jbang.core.commands.tui.TuiHelper.*; class RoutesTab extends AbstractTab { @@ -1285,19 +1285,19 @@ class RoutesTab extends AbstractTab { } private String routeSortLabel(String label, String column) { - return MonitorContext.sortLabel(label, column, routeSort, routeSortReversed); + return sortLabel(label, column, routeSort, routeSortReversed); } private Style routeSortStyle(String column) { - return MonitorContext.sortStyle(column, routeSort); + return sortStyle(column, routeSort); } private String routeTopSortLabel(String label, String column) { - return MonitorContext.sortLabel(label, column, routeTopSort, routeTopSortReversed); + return sortLabel(label, column, routeTopSort, routeTopSortReversed); } private Style routeTopSortStyle(String column) { - return MonitorContext.sortStyle(column, routeTopSort); + return sortStyle(column, routeTopSort); } // ---- Route actions ---- diff --git a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/RunOptionsForm.java b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/RunOptionsForm.java index ca29642fff48..27bbfdf87646 100644 --- a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/RunOptionsForm.java +++ b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/RunOptionsForm.java @@ -34,8 +34,8 @@ import dev.tamboui.widgets.input.TextInput; import dev.tamboui.widgets.input.TextInputState; import dev.tamboui.widgets.paragraph.Paragraph; -import static org.apache.camel.dsl.jbang.core.commands.tui.MonitorContext.hint; -import static org.apache.camel.dsl.jbang.core.commands.tui.MonitorContext.hintLast; +import static org.apache.camel.dsl.jbang.core.commands.tui.TuiHelper.hint; +import static org.apache.camel.dsl.jbang.core.commands.tui.TuiHelper.hintLast; class RunOptionsForm { diff --git a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/SearchHighlighter.java b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/SearchHighlighter.java index 49a90dadfc2e..a322e4d7b34a 100644 --- a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/SearchHighlighter.java +++ b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/SearchHighlighter.java @@ -30,7 +30,9 @@ import dev.tamboui.tui.event.KeyCode; import dev.tamboui.tui.event.KeyEvent; import dev.tamboui.widgets.input.TextInputState; -import static org.apache.camel.dsl.jbang.core.commands.tui.MonitorContext.*; +import static org.apache.camel.dsl.jbang.core.commands.tui.TuiHelper.*; +import static org.apache.camel.dsl.jbang.core.commands.tui.TuiHelper.hint; +import static org.apache.camel.dsl.jbang.core.commands.tui.TuiHelper.hintLast; /** * Shared find/highlight search logic used by LogTab and SourceViewer. diff --git a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/SendMessagePopup.java b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/SendMessagePopup.java index 04661c6cfa39..2137a88cf85b 100644 --- a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/SendMessagePopup.java +++ b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/SendMessagePopup.java @@ -47,7 +47,9 @@ import org.apache.camel.dsl.jbang.core.common.PathUtils; import org.apache.camel.util.json.JsonArray; import org.apache.camel.util.json.JsonObject; -import static org.apache.camel.dsl.jbang.core.commands.tui.MonitorContext.*; +import static org.apache.camel.dsl.jbang.core.commands.tui.TuiHelper.*; +import static org.apache.camel.dsl.jbang.core.commands.tui.TuiHelper.hint; +import static org.apache.camel.dsl.jbang.core.commands.tui.TuiHelper.hintLast; class SendMessagePopup { @@ -442,7 +444,7 @@ class SendMessagePopup { Path actionFile = ctx.getActionFile(targetPid); PathUtils.writeTextSafely(root.toJson(), actionFile); - JsonObject response = MonitorContext.pollJsonResponse(outputFile, 25000); + JsonObject response = TuiHelper.pollJsonResponse(outputFile, 25000); PathUtils.deleteFile(outputFile); if (response == null) { diff --git a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/ShellPanel.java b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/ShellPanel.java index daabad94ad64..2f58b6ff00c0 100644 --- a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/ShellPanel.java +++ b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/ShellPanel.java @@ -197,7 +197,7 @@ class ShellPanel { if (!visible || lastArea == null) { return false; } - if (!AbstractTab.contains(lastArea, me.x(), me.y())) { + if (!TuiHelper.contains(lastArea, me.x(), me.y())) { return false; } if (me.kind() == MouseEventKind.SCROLL_UP) { @@ -335,9 +335,9 @@ class ShellPanel { } void renderFooter(List<Span> spans) { - MonitorContext.hint(spans, "F6", "close"); - MonitorContext.hint(spans, "Shift+F6", "resize (" + anim.cyclePercent() + "%)"); - MonitorContext.hint(spans, "PgUp/Dn", "scroll"); + TuiHelper.hint(spans, "F6", "close"); + TuiHelper.hint(spans, "Shift+F6", "resize (" + anim.cyclePercent() + "%)"); + TuiHelper.hint(spans, "PgUp/Dn", "scroll"); } private List<Line> renderLiveView(long[] screen, int width, int height) { diff --git a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/SourceViewer.java b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/SourceViewer.java index 6350d1adb036..8dc3a4d23316 100644 --- a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/SourceViewer.java +++ b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/SourceViewer.java @@ -51,7 +51,7 @@ import org.apache.camel.util.json.JsonArray; import org.apache.camel.util.json.JsonObject; import org.apache.camel.util.json.Jsoner; -import static org.apache.camel.dsl.jbang.core.commands.tui.MonitorContext.pollJsonResponse; +import static org.apache.camel.dsl.jbang.core.commands.tui.TuiHelper.pollJsonResponse; /** * Reusable source code viewer with syntax highlighting, scrolling, and line-number display. Can be used by any tab that @@ -305,22 +305,22 @@ class SourceViewer { if (search.hasFindTerm()) { search.renderFindStatus(spans); } else { - MonitorContext.hint(spans, "Esc/c", "close"); + TuiHelper.hint(spans, "Esc/c", "close"); } - MonitorContext.hint(spans, "↑↓", "navigate"); + TuiHelper.hint(spans, "↑↓", "navigate"); if (currentRouteId != null) { - MonitorContext.hint(spans, "Y", "yaml"); - MonitorContext.hint(spans, "J", "java"); - MonitorContext.hint(spans, "X", "xml"); + TuiHelper.hint(spans, "Y", "yaml"); + TuiHelper.hint(spans, "J", "java"); + TuiHelper.hint(spans, "X", "xml"); } search.renderSearchHints(spans); - MonitorContext.hint(spans, "w", "wrap" + (wordWrap ? " [on]" : " [off]")); + TuiHelper.hint(spans, "w", "wrap" + (wordWrap ? " [on]" : " [off]")); if (!wordWrap) { - MonitorContext.hint(spans, "←→", "horizontal"); + TuiHelper.hint(spans, "←→", "horizontal"); } - MonitorContext.hint(spans, "PgUp/PgDn", "page"); + TuiHelper.hint(spans, "PgUp/PgDn", "page"); if (onLineSelected != null) { - MonitorContext.hint(spans, "Enter", "select node"); + TuiHelper.hint(spans, "Enter", "select node"); } } diff --git a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/SpansTab.java b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/SpansTab.java index 29fdef1e0137..85d5e5de9667 100644 --- a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/SpansTab.java +++ b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/SpansTab.java @@ -54,6 +54,8 @@ import dev.tamboui.widgets.table.TableState; import org.apache.camel.util.json.JsonArray; import org.apache.camel.util.json.JsonObject; +import static org.apache.camel.dsl.jbang.core.commands.tui.TuiHelper.*; + class SpansTab extends AbstractTab { private static final int MOUSE_SCROLL_LINES = 3; @@ -295,7 +297,7 @@ class SpansTab extends AbstractTab { public void render(Frame frame, Rect area) { IntegrationInfo info = ctx.findSelectedIntegration(); if (info == null) { - MonitorContext.renderNoSelection(frame, area); + renderNoSelection(frame, area); return; } @@ -374,12 +376,12 @@ class SpansTab extends AbstractTab { Cell.from(shortId(ts.traceId)), Cell.from(ts.rootRouteId != null ? ts.rootRouteId : ""), Cell.from(ts.rootName != null ? ts.rootName : "?"), - MonitorContext.rightCell(String.valueOf(ts.spanCount), 5), - MonitorContext.rightCell(String.valueOf(ts.routeCount), 5), + rightCell(String.valueOf(ts.spanCount), 5), + rightCell(String.valueOf(ts.routeCount), 5), Cell.from(ts.remoteComponents.isEmpty() ? "-" : ts.remoteComponents), Cell.from(Span.styled(ts.hasError ? "ERROR" : "OK", statusStyle)), Cell.from(ts.totalDurationMs + "ms"), - MonitorContext.rightCell(String.valueOf(ts.maxDepth), 5))); + rightCell(String.valueOf(ts.maxDepth), 5))); } String title; @@ -641,28 +643,28 @@ class SpansTab extends AbstractTab { @Override public void renderFooter(List<Span> spans) { if (waterfallView) { - MonitorContext.hint(spans, "Esc", "back"); - MonitorContext.hint(spans, "F5", "refresh"); - MonitorContext.hint(spans, "c", camelOnly ? "camel-only [on]" : "camel-only [off]"); - MonitorContext.hint(spans, "p", showProcessors ? "processors [on]" : "processors [off]"); - MonitorContext.hint(spans, "↑↓", "navigate"); - MonitorContext.hintLast(spans, "PgUp/Dn", "page"); + hint(spans, "Esc", "back"); + hint(spans, "F5", "refresh"); + hint(spans, "c", camelOnly ? "camel-only [on]" : "camel-only [off]"); + hint(spans, "p", showProcessors ? "processors [on]" : "processors [off]"); + hint(spans, "↑↓", "navigate"); + hintLast(spans, "PgUp/Dn", "page"); } else if (filterInputActive) { spans.add(Span.styled(" /", Style.EMPTY.fg(Color.YELLOW).bold())); spans.add(Span.raw(filterInputState.text() + "█ ")); - MonitorContext.hint(spans, "Enter", "filter"); - MonitorContext.hintLast(spans, "Esc", "cancel"); + hint(spans, "Enter", "filter"); + hintLast(spans, "Esc", "cancel"); } else { - MonitorContext.hint(spans, "Esc", filterTerm != null ? "clear" : "back"); - MonitorContext.hint(spans, "F5", "refresh"); - MonitorContext.hint(spans, "Enter", "waterfall"); + hint(spans, "Esc", filterTerm != null ? "clear" : "back"); + hint(spans, "F5", "refresh"); + hint(spans, "Enter", "waterfall"); if (filterTerm != null) { spans.add(Span.styled(" /", Style.EMPTY.fg(Color.YELLOW).bold())); spans.add(Span.raw("\"" + filterTerm + "\" ")); } else { - MonitorContext.hint(spans, "/", "filter"); + hint(spans, "/", "filter"); } - MonitorContext.hintLast(spans, "↑↓", "navigate"); + hintLast(spans, "↑↓", "navigate"); } } @@ -949,7 +951,7 @@ class SpansTab extends AbstractTab { } private String sortLabel(String label, String column) { - return MonitorContext.sortLabel(label, column, sortColumn, sortReversed); + return sortLabel(label, column, sortColumn, sortReversed); } private Style sortStyle(String column) { diff --git a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/SqlQueryTab.java b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/SqlQueryTab.java index 5db2f592147a..6b6af98490e8 100644 --- a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/SqlQueryTab.java +++ b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/SqlQueryTab.java @@ -52,7 +52,7 @@ import org.apache.camel.dsl.jbang.core.common.PathUtils; import org.apache.camel.util.json.JsonArray; import org.apache.camel.util.json.JsonObject; -import static org.apache.camel.dsl.jbang.core.commands.tui.MonitorContext.*; +import static org.apache.camel.dsl.jbang.core.commands.tui.TuiHelper.*; class SqlQueryTab extends AbstractTab { diff --git a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/SqlTraceTab.java b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/SqlTraceTab.java index 30eb57254ea7..4701b41d23dc 100644 --- a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/SqlTraceTab.java +++ b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/SqlTraceTab.java @@ -46,7 +46,7 @@ import dev.tamboui.widgets.table.Table; import org.apache.camel.util.json.JsonArray; import org.apache.camel.util.json.JsonObject; -import static org.apache.camel.dsl.jbang.core.commands.tui.MonitorContext.*; +import static org.apache.camel.dsl.jbang.core.commands.tui.TuiHelper.*; class SqlTraceTab extends AbstractTableTab { diff --git a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/StartupTab.java b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/StartupTab.java index 8f038bb41777..48337147cc30 100644 --- a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/StartupTab.java +++ b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/StartupTab.java @@ -45,7 +45,7 @@ import org.apache.camel.dsl.jbang.core.common.PathUtils; import org.apache.camel.util.json.JsonArray; import org.apache.camel.util.json.JsonObject; -import static org.apache.camel.dsl.jbang.core.commands.tui.MonitorContext.*; +import static org.apache.camel.dsl.jbang.core.commands.tui.TuiHelper.*; class StartupTab extends AbstractTab { diff --git a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/StopAllPopup.java b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/StopAllPopup.java index 267d71406b3e..4598d2cb77e0 100644 --- a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/StopAllPopup.java +++ b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/StopAllPopup.java @@ -36,8 +36,8 @@ import dev.tamboui.widgets.paragraph.Paragraph; import org.apache.camel.dsl.jbang.core.common.CommandLineHelper; import org.apache.camel.dsl.jbang.core.common.PathUtils; -import static org.apache.camel.dsl.jbang.core.commands.tui.MonitorContext.hint; -import static org.apache.camel.dsl.jbang.core.commands.tui.MonitorContext.hintLast; +import static org.apache.camel.dsl.jbang.core.commands.tui.TuiHelper.hint; +import static org.apache.camel.dsl.jbang.core.commands.tui.TuiHelper.hintLast; class StopAllPopup { diff --git a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/ThreadsTab.java b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/ThreadsTab.java index 91dbc03b3035..f5fb6889c85a 100644 --- a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/ThreadsTab.java +++ b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/ThreadsTab.java @@ -45,7 +45,7 @@ import org.apache.camel.dsl.jbang.core.common.PathUtils; import org.apache.camel.util.json.JsonArray; import org.apache.camel.util.json.JsonObject; -import static org.apache.camel.dsl.jbang.core.commands.tui.MonitorContext.*; +import static org.apache.camel.dsl.jbang.core.commands.tui.TuiHelper.*; class ThreadsTab extends AbstractTableTab { diff --git a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/TuiHelper.java b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/TuiHelper.java index 586d04ec5a0c..b3889d1477ee 100644 --- a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/TuiHelper.java +++ b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/TuiHelper.java @@ -23,6 +23,7 @@ import java.util.ArrayList; import java.util.List; import java.util.function.Function; +import dev.tamboui.layout.Rect; import dev.tamboui.style.AnsiColor; import dev.tamboui.style.Color; import dev.tamboui.style.Style; @@ -427,6 +428,157 @@ final class TuiHelper { return DURATION_BAND_STYLES[bandIndex]; } + // ---- UI helpers ---- + + static void hint(List<Span> spans, String key, String label) { + spans.add(Span.styled(" " + key + " ", Theme.hintKey())); + spans.add(Span.raw(" " + label + " ")); + } + + static void hintLast(List<Span> spans, String key, String label) { + spans.add(Span.styled(" " + key + " ", Theme.hintKey())); + spans.add(Span.raw(" " + label)); + } + + static boolean contains(Rect rect, int x, int y) { + return rect != null + && x >= rect.x() && x < rect.x() + rect.width() + && y >= rect.y() && y < rect.y() + rect.height(); + } + + static int compareStr(String a, String b) { + if (a == null && b == null) { + return 0; + } + if (a == null) { + return 1; + } + if (b == null) { + return -1; + } + return a.compareToIgnoreCase(b); + } + + // ---- Data formatting helpers ---- + + static final String[] SMALL_CAMEL = { + " ,,__", + "/o. \\___/\\", + "\\__/ \\", + " | | |", + " | | |~", + " (_) (_) (_)", + }; + + static JsonObject pollJsonResponse(Path outputFile, long timeout) { + long start = System.currentTimeMillis(); + while (System.currentTimeMillis() - start < timeout) { + try { + Thread.sleep(100); + if (Files.exists(outputFile) && outputFile.toFile().length() > 0) { + String text = Files.readString(outputFile); + return (JsonObject) Jsoner.deserialize(text); + } + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + return null; + } catch (Exception e) { + // ignore + } + } + return null; + } + + static String formatSinceLast(IntegrationInfo info) { + return formatSinceLast(info.sinceLastStarted, info.sinceLastCompleted, info.sinceLastFailed); + } + + static String formatSinceLast(String started, String completed, String failed) { + StringBuilder sb = new StringBuilder(); + if (started != null) { + sb.append(started); + } + if (completed != null) { + if (!sb.isEmpty()) { + sb.append('/'); + } + sb.append(completed); + } + if (failed != null) { + if (!sb.isEmpty()) { + sb.append('/'); + } + sb.append(failed); + } + return sb.toString(); + } + + static String formatSinceLastRoute(RouteInfo route) { + return formatSinceLast(route.sinceLastStarted, route.sinceLastCompleted, route.sinceLastFailed); + } + + static String formatLoad(String l1, String l5, String l15) { + String s1 = l1 != null && !"0.00".equals(l1) ? l1 : "0"; + String s5 = l5 != null && !"0.00".equals(l5) ? l5 : "0"; + String s15 = l15 != null && !"0.00".equals(l15) ? l15 : "0"; + return s1 + "/" + s5 + "/" + s15; + } + + static String formatMemory(long used, long max) { + if (used <= 0) { + return ""; + } + String u = formatBytes(used); + if (max > 0) { + return u + "/" + formatBytes(max); + } + return u; + } + + static String formatBytes(long bytes) { + if (bytes < 1024) { + return bytes + "B"; + } + if (bytes < 1024 * 1024) { + return (bytes / 1024) + "K"; + } + return (bytes / (1024 * 1024)) + "M"; + } + + static String formatThreads(int count, int peak) { + if (count <= 0) { + return ""; + } + return count + "/" + peak; + } + + static Style topTimeStyle(long ms) { + if (ms >= 1000) { + return Style.EMPTY.fg(Color.LIGHT_RED).bold(); + } else if (ms >= 100) { + return Style.EMPTY.fg(Color.YELLOW); + } + return Style.EMPTY; + } + + static Style topDeltaStyle(long delta) { + if (delta > 0) { + return Style.EMPTY.fg(Color.LIGHT_RED); + } else if (delta < 0) { + return Style.EMPTY.fg(Color.GREEN); + } + return Style.EMPTY; + } + + static String buildBar(long value, long maxValue, int maxWidth) { + if (value <= 0 || maxValue <= 0) { + return ""; + } + int len = (int) Math.round((double) value / maxValue * maxWidth); + len = Math.max(len > 0 ? 1 : 0, Math.min(len, maxWidth)); + return "█".repeat(len); + } + static String shortTypeName(String type) { if (type == null) { return "null"; diff --git a/dsl/camel-jbang/camel-jbang-plugin-tui/src/test/java/org/apache/camel/dsl/jbang/core/commands/tui/CamelMonitorTest.java b/dsl/camel-jbang/camel-jbang-plugin-tui/src/test/java/org/apache/camel/dsl/jbang/core/commands/tui/CamelMonitorTest.java index 09925b08a261..7b154e5c86e1 100644 --- a/dsl/camel-jbang/camel-jbang-plugin-tui/src/test/java/org/apache/camel/dsl/jbang/core/commands/tui/CamelMonitorTest.java +++ b/dsl/camel-jbang/camel-jbang-plugin-tui/src/test/java/org/apache/camel/dsl/jbang/core/commands/tui/CamelMonitorTest.java @@ -24,7 +24,7 @@ import dev.tamboui.tui.event.KeyCode; import dev.tamboui.tui.event.KeyEvent; import org.junit.jupiter.api.Test; -import static org.apache.camel.dsl.jbang.core.commands.tui.MonitorContext.hint; +import static org.apache.camel.dsl.jbang.core.commands.tui.TuiHelper.hint; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; diff --git a/dsl/camel-jbang/camel-jbang-plugin-tui/src/test/java/org/apache/camel/dsl/jbang/core/commands/tui/MonitorContextRenderTest.java b/dsl/camel-jbang/camel-jbang-plugin-tui/src/test/java/org/apache/camel/dsl/jbang/core/commands/tui/MonitorContextRenderTest.java index d299f8d0eafe..1cd58e629761 100644 --- a/dsl/camel-jbang/camel-jbang-plugin-tui/src/test/java/org/apache/camel/dsl/jbang/core/commands/tui/MonitorContextRenderTest.java +++ b/dsl/camel-jbang/camel-jbang-plugin-tui/src/test/java/org/apache/camel/dsl/jbang/core/commands/tui/MonitorContextRenderTest.java @@ -41,7 +41,7 @@ class MonitorContextRenderTest { Buffer buffer = Buffer.empty(area); Frame frame = Frame.forTesting(buffer); - MonitorContext.renderNoSelection(frame, area); + AbstractTab.renderNoSelection(frame, area); String rendered = HealthTabRenderTest.bufferToString(buffer); assertTrue(rendered.contains("No integration selected"), @@ -54,7 +54,7 @@ class MonitorContextRenderTest { Buffer buffer = Buffer.empty(area); Frame frame = Frame.forTesting(buffer); - MonitorContext.renderNoSelection(frame, area); + AbstractTab.renderNoSelection(frame, area); String rendered = HealthTabRenderTest.bufferToString(buffer); // The block title and prompt text should appear in the buffer @@ -68,7 +68,7 @@ class MonitorContextRenderTest { Buffer buffer = Buffer.empty(area); Frame frame = Frame.forTesting(buffer); - MonitorContext.renderNoSelection(frame, area); + AbstractTab.renderNoSelection(frame, area); boolean foundBold = false; for (int y = 0; y < buffer.height(); y++) { @@ -90,7 +90,7 @@ class MonitorContextRenderTest { @Test void hintAddsKeyAndLabel() { List<Span> spans = new ArrayList<>(); - MonitorContext.hint(spans, "Esc", "back"); + TuiHelper.hint(spans, "Esc", "back"); assertEquals(2, spans.size(), "hint should add exactly 2 spans"); assertTrue(spans.get(0).content().contains("Esc"), "First span should contain the key"); @@ -100,7 +100,7 @@ class MonitorContextRenderTest { @Test void hintKeyUsesThemeBoldStyle() { List<Span> spans = new ArrayList<>(); - MonitorContext.hint(spans, "s", "sort"); + TuiHelper.hint(spans, "s", "sort"); Span keySpan = spans.get(0); assertTrue(keySpan.style().fg().isPresent(), "Key span should have a foreground color"); @@ -112,7 +112,7 @@ class MonitorContextRenderTest { @Test void hintLabelHasTrailingSpaces() { List<Span> spans = new ArrayList<>(); - MonitorContext.hint(spans, "x", "action"); + TuiHelper.hint(spans, "x", "action"); Span labelSpan = spans.get(1); assertTrue(labelSpan.content().endsWith(" "), @@ -122,7 +122,7 @@ class MonitorContextRenderTest { @Test void hintLastDoesNotHaveTrailingSpaces() { List<Span> spans = new ArrayList<>(); - MonitorContext.hintLast(spans, "q", "quit"); + TuiHelper.hintLast(spans, "q", "quit"); Span labelSpan = spans.get(1); assertEquals(" quit", labelSpan.content(), @@ -131,7 +131,7 @@ class MonitorContextRenderTest { @Test void rightCellRendersRightAligned() { - var cell = MonitorContext.rightCell("42", 8); + var cell = AbstractTab.rightCell("42", 8); // rightCell uses String.format("%8s", "42") → " 42" String content = extractCellContent(cell); assertTrue(content.endsWith("42"), "Content should end with the value"); @@ -140,7 +140,7 @@ class MonitorContextRenderTest { @Test void rightCellWithStyleAppliesStyle() { - var cell = MonitorContext.rightCell("5", 6, dev.tamboui.style.Style.EMPTY.fg(Color.LIGHT_RED)); + var cell = AbstractTab.rightCell("5", 6, dev.tamboui.style.Style.EMPTY.fg(Color.LIGHT_RED)); // The cell should have styled content String content = extractCellContent(cell); assertTrue(content.contains("5"), "Should contain the value"); @@ -148,7 +148,7 @@ class MonitorContextRenderTest { @Test void centerCellCentersText() { - var cell = MonitorContext.centerCell("x", 6); + var cell = AbstractTab.centerCell("x", 6); String content = extractCellContent(cell); // "x" centered in width 6: " x" (leftPad = (6-1)/2 = 2) assertTrue(content.startsWith(" "), "Content should have leading padding"); @@ -157,22 +157,22 @@ class MonitorContextRenderTest { @Test void sortLabelShowsIndicatorForActiveColumn() { - String label = MonitorContext.sortLabel("NAME", "name", "name", false); + String label = AbstractTab.sortLabel("NAME", "name", "name", false); assertEquals("NAME▼", label, "Active sort column should have descending indicator"); - String reversed = MonitorContext.sortLabel("NAME", "name", "name", true); + String reversed = AbstractTab.sortLabel("NAME", "name", "name", true); assertEquals("NAME▲", reversed, "Reversed sort should have ascending indicator"); } @Test void sortLabelNoIndicatorForInactiveColumn() { - String label = MonitorContext.sortLabel("NAME", "name", "status", false); + String label = AbstractTab.sortLabel("NAME", "name", "status", false); assertEquals("NAME", label, "Inactive column should have no indicator"); } @Test void sortStyleActiveColumnIsYellowBold() { - var style = MonitorContext.sortStyle("name", "name"); + var style = AbstractTab.sortStyle("name", "name"); assertEquals(Color.YELLOW, style.fg().orElse(null), "Active sort column should be YELLOW"); assertTrue(style.effectiveModifiers().contains(dev.tamboui.style.Modifier.BOLD), "Active sort column should be BOLD"); @@ -180,7 +180,7 @@ class MonitorContextRenderTest { @Test void sortStyleInactiveColumnIsBoldOnly() { - var style = MonitorContext.sortStyle("name", "status"); + var style = AbstractTab.sortStyle("name", "status"); assertTrue(style.fg().isEmpty() || !Color.YELLOW.equals(style.fg().get()), "Inactive column should not be YELLOW"); assertTrue(style.effectiveModifiers().contains(dev.tamboui.style.Modifier.BOLD), diff --git a/dsl/camel-jbang/camel-jbang-plugin-tui/src/test/java/org/apache/camel/dsl/jbang/core/commands/tui/MonitorContextTest.java b/dsl/camel-jbang/camel-jbang-plugin-tui/src/test/java/org/apache/camel/dsl/jbang/core/commands/tui/MonitorContextTest.java index 58cbf0b67b4b..daff89970204 100644 --- a/dsl/camel-jbang/camel-jbang-plugin-tui/src/test/java/org/apache/camel/dsl/jbang/core/commands/tui/MonitorContextTest.java +++ b/dsl/camel-jbang/camel-jbang-plugin-tui/src/test/java/org/apache/camel/dsl/jbang/core/commands/tui/MonitorContextTest.java @@ -30,37 +30,37 @@ class MonitorContextTest { @Test void formatSinceLastAllThreePresent() { - String result = MonitorContext.formatSinceLast("1s", "2s", "3s"); + String result = TuiHelper.formatSinceLast("1s", "2s", "3s"); assertEquals("1s/2s/3s", result); } @Test void formatSinceLastOnlyStarted() { - String result = MonitorContext.formatSinceLast("5s", null, null); + String result = TuiHelper.formatSinceLast("5s", null, null); assertEquals("5s", result); } @Test void formatSinceLastOnlyCompleted() { - String result = MonitorContext.formatSinceLast(null, "10s", null); + String result = TuiHelper.formatSinceLast(null, "10s", null); assertEquals("10s", result); } @Test void formatSinceLastOnlyFailed() { - String result = MonitorContext.formatSinceLast(null, null, "7s"); + String result = TuiHelper.formatSinceLast(null, null, "7s"); assertEquals("7s", result); } @Test void formatSinceLastNonePresent() { - String result = MonitorContext.formatSinceLast(null, null, null); + String result = TuiHelper.formatSinceLast(null, null, null); assertEquals("", result); } @Test void formatSinceLastStartedAndFailed() { - String result = MonitorContext.formatSinceLast("1s", null, "3s"); + String result = TuiHelper.formatSinceLast("1s", null, "3s"); assertEquals("1s/3s", result); } @@ -68,25 +68,25 @@ class MonitorContextTest { @Test void formatLoadNonZeroValues() { - String result = MonitorContext.formatLoad("1.23", "4.56", "7.89"); + String result = TuiHelper.formatLoad("1.23", "4.56", "7.89"); assertEquals("1.23/4.56/7.89", result); } @Test void formatLoadZeroCollapse() { - String result = MonitorContext.formatLoad("0.00", "0.00", "0.00"); + String result = TuiHelper.formatLoad("0.00", "0.00", "0.00"); assertEquals("0/0/0", result); } @Test void formatLoadNullHandling() { - String result = MonitorContext.formatLoad(null, null, null); + String result = TuiHelper.formatLoad(null, null, null); assertEquals("0/0/0", result); } @Test void formatLoadMixedZeroAndNonZero() { - String result = MonitorContext.formatLoad("1.50", "0.00", "0.75"); + String result = TuiHelper.formatLoad("1.50", "0.00", "0.75"); assertEquals("1.50/0/0.75", result); } @@ -95,20 +95,20 @@ class MonitorContextTest { @Test void formatMemoryBothPositive() { // 512MB used, 1GB max - String result = MonitorContext.formatMemory(536870912L, 1073741824L); + String result = TuiHelper.formatMemory(536870912L, 1073741824L); assertEquals("512M/1024M", result); } @Test void formatMemoryMaxZeroShowsUsedOnly() { // 1048576 bytes = 1M (1024 * 1024) - String result = MonitorContext.formatMemory(1048576L, 0L); + String result = TuiHelper.formatMemory(1048576L, 0L); assertEquals("1M", result); } @Test void formatMemoryUsedZeroReturnsEmpty() { - String result = MonitorContext.formatMemory(0L, 1048576L); + String result = TuiHelper.formatMemory(0L, 1048576L); assertEquals("", result); } @@ -116,55 +116,55 @@ class MonitorContextTest { @Test void formatBytesRange() { - assertEquals("500B", MonitorContext.formatBytes(500)); + assertEquals("500B", TuiHelper.formatBytes(500)); } @Test void formatBytesKilobytes() { - assertEquals("1K", MonitorContext.formatBytes(1024)); - assertEquals("10K", MonitorContext.formatBytes(10240)); + assertEquals("1K", TuiHelper.formatBytes(1024)); + assertEquals("10K", TuiHelper.formatBytes(10240)); } @Test void formatBytesMegabytes() { - assertEquals("1M", MonitorContext.formatBytes(1048576)); - assertEquals("100M", MonitorContext.formatBytes(104857600)); + assertEquals("1M", TuiHelper.formatBytes(1048576)); + assertEquals("100M", TuiHelper.formatBytes(104857600)); } // ---- buildBar tests ---- @Test void buildBarFull() { - String bar = MonitorContext.buildBar(100, 100, 10); + String bar = TuiHelper.buildBar(100, 100, 10); assertEquals(10, bar.length()); } @Test void buildBarPartial() { - String bar = MonitorContext.buildBar(50, 100, 10); + String bar = TuiHelper.buildBar(50, 100, 10); assertEquals(5, bar.length()); } @Test void buildBarZeroValue() { - String bar = MonitorContext.buildBar(0, 100, 10); + String bar = TuiHelper.buildBar(0, 100, 10); assertEquals("", bar); } @Test void buildBarZeroMax() { - String bar = MonitorContext.buildBar(50, 0, 10); + String bar = TuiHelper.buildBar(50, 0, 10); assertEquals("", bar); } @Test void buildBarSmallValueRoundsCorrectly() { // 1/1000 * 10 rounds to 0, buildBar returns empty for zero-length - String bar = MonitorContext.buildBar(1, 1000, 10); + String bar = TuiHelper.buildBar(1, 1000, 10); assertEquals("", bar); // A value large enough to produce at least one block (>= 1/maxWidth ratio) - String bar2 = MonitorContext.buildBar(100, 1000, 10); + String bar2 = TuiHelper.buildBar(100, 1000, 10); assertTrue(bar2.length() >= 1); } @@ -172,20 +172,20 @@ class MonitorContextTest { @Test void topTimeStyleOver1000ms() { - Style style = MonitorContext.topTimeStyle(1000); + Style style = TuiHelper.topTimeStyle(1000); assertTrue(style.effectiveModifiers().contains(Modifier.BOLD)); assertEquals(Color.LIGHT_RED, style.fg().orElse(null)); } @Test void topTimeStyleOver100ms() { - Style style = MonitorContext.topTimeStyle(500); + Style style = TuiHelper.topTimeStyle(500); assertEquals(Color.YELLOW, style.fg().orElse(null)); } @Test void topTimeStyleUnder100ms() { - Style style = MonitorContext.topTimeStyle(50); + Style style = TuiHelper.topTimeStyle(50); assertEquals(Style.EMPTY, style); } @@ -193,19 +193,19 @@ class MonitorContextTest { @Test void topDeltaStylePositive() { - Style style = MonitorContext.topDeltaStyle(10); + Style style = TuiHelper.topDeltaStyle(10); assertEquals(Color.LIGHT_RED, style.fg().orElse(null)); } @Test void topDeltaStyleNegative() { - Style style = MonitorContext.topDeltaStyle(-5); + Style style = TuiHelper.topDeltaStyle(-5); assertEquals(Color.GREEN, style.fg().orElse(null)); } @Test void topDeltaStyleZero() { - Style style = MonitorContext.topDeltaStyle(0); + Style style = TuiHelper.topDeltaStyle(0); assertEquals(Style.EMPTY, style); } @@ -213,23 +213,23 @@ class MonitorContextTest { @Test void compareStrBothNull() { - assertEquals(0, MonitorContext.compareStr(null, null)); + assertEquals(0, TuiHelper.compareStr(null, null)); } @Test void compareStrFirstNull() { - assertEquals(1, MonitorContext.compareStr(null, "b")); + assertEquals(1, TuiHelper.compareStr(null, "b")); } @Test void compareStrSecondNull() { - assertEquals(-1, MonitorContext.compareStr("a", null)); + assertEquals(-1, TuiHelper.compareStr("a", null)); } @Test void compareStrCaseInsensitive() { - assertEquals(0, MonitorContext.compareStr("ABC", "abc")); - assertTrue(MonitorContext.compareStr("abc", "xyz") < 0); - assertTrue(MonitorContext.compareStr("xyz", "abc") > 0); + assertEquals(0, TuiHelper.compareStr("ABC", "abc")); + assertTrue(TuiHelper.compareStr("abc", "xyz") < 0); + assertTrue(TuiHelper.compareStr("xyz", "abc") > 0); } }
