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

davsclaus pushed a commit to branch feature/CAMEL-24237-catalog-docs
in repository https://gitbox.apache.org/repos/asf/camel.git

commit 204b004b8912bde98b49240ca157df8a32944667
Author: Claus Ibsen <[email protected]>
AuthorDate: Wed Jul 22 11:39:58 2026 +0200

    CAMEL-24237: TUI Catalog tab doc viewer via d key
    
    Press d in the Catalog tab to open the full AsciiDoc documentation
    for the selected artifact in the shared DocViewerPopup. The doc is
    loaded from the catalog and converted to Markdown for display.
    
    Co-Authored-By: Claude Opus 4.6 <[email protected]>
    Signed-off-by: Claus Ibsen <[email protected]>
---
 .../dsl/jbang/core/commands/tui/ActionsPopup.java  |  5 ++
 .../dsl/jbang/core/commands/tui/CamelMonitor.java  |  1 +
 .../dsl/jbang/core/commands/tui/CatalogTab.java    | 62 ++++++++++++++++++----
 .../jbang/core/commands/tui/MonitorContext.java    |  1 +
 4 files changed, 58 insertions(+), 11 deletions(-)

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 e29e3f22e96c..0e7015c5309f 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
@@ -1090,6 +1090,11 @@ class ActionsPopup {
         }
     }
 
+    void openMarkdown(String title, String markdown) {
+        showActionsMenu = false;
+        docViewerPopup.openMarkdown(title, markdown);
+    }
+
     private void setNotification(String msg, boolean error) {
         if (notificationCallback != null) {
             notificationCallback.accept(msg, error);
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 c4807f6c9891..1fb42156ad48 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
@@ -268,6 +268,7 @@ public class CamelMonitor extends CamelCommand {
         actionsPopup.setMonitorContext(ctx);
         actionsPopup.setNotificationCallback((msg, error) -> 
setNotification(msg, error));
         ctx.notificationCallback = (msg, error) -> setNotification(msg, error);
+        ctx.openMarkdownCallback = actionsPopup::openMarkdown;
         actionsPopup.setResetStatsAction(this::resetStats);
         shellPanel.setContext(ctx);
         aiPanel.setContext(ctx);
diff --git 
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/CatalogTab.java
 
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/CatalogTab.java
index 825790433d5e..325799151b33 100644
--- 
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/CatalogTab.java
+++ 
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/CatalogTab.java
@@ -64,6 +64,7 @@ class CatalogTab extends AbstractTableTab {
     private String filterTerm;
     private int scopeIndex;
     private boolean fullCatalog;
+    private CamelCatalog catalog;
     private List<CatalogEntry> allEntries = Collections.emptyList();
     private List<CatalogEntry> filteredEntries = Collections.emptyList();
     private String lastPid;
@@ -94,6 +95,7 @@ class CatalogTab extends AbstractTableTab {
         filterTerm = null;
         filterInputActive = false;
         scopeIndex = 0;
+        catalog = null;
         lastPid = null;
         errorMessage = null;
         dataLoaded = false;
@@ -134,6 +136,10 @@ class CatalogTab extends AbstractTableTab {
             loadCatalogData();
             return true;
         }
+        if (ke.isCharIgnoreCase('d')) {
+            openDocViewer();
+            return true;
+        }
         return false;
     }
 
@@ -334,6 +340,30 @@ class CatalogTab extends AbstractTableTab {
                 area);
     }
 
+    private void openDocViewer() {
+        if (ctx.openMarkdownCallback == null || catalog == null) {
+            return;
+        }
+        List<CatalogEntry> sorted = new ArrayList<>(filteredEntries);
+        sorted.sort(this::sortEntry);
+        Integer sel = tableState.selected();
+        if (sel == null || sel < 0 || sel >= sorted.size()) {
+            return;
+        }
+        CatalogEntry entry = sorted.get(sel);
+        String docName = switch (entry.kind) {
+            case "component" -> entry.name + "-component";
+            case "dataformat" -> entry.name + "-dataformat";
+            case "language" -> entry.name + "-language";
+            default -> entry.name;
+        };
+        String adoc = catalog.asciiDoc(docName);
+        if (adoc != null) {
+            String md = DocHelper.asciidocToMarkdown(adoc);
+            ctx.openMarkdownCallback.accept(entry.name, md);
+        }
+    }
+
     private void addDetailField(List<Line> lines, String label, String value, 
int width) {
         if (value == null || value.isEmpty()) {
             return;
@@ -377,6 +407,7 @@ class CatalogTab extends AbstractTableTab {
         hint(spans, "s", "sort");
         hint(spans, "a", fullCatalog ? "app only" : "all");
         hint(spans, "f", "scope [" + SCOPES[scopeIndex] + "]");
+        hint(spans, "d", "doc");
         if (filterTerm != null) {
             spans.add(Span.styled("  /", Theme.label().bold()));
             spans.add(Span.raw("\"" + filterTerm + "\"  "));
@@ -422,7 +453,7 @@ class CatalogTab extends AbstractTableTab {
                 if (!full) {
                     DependencyLoader.LoadResult result = 
DependencyLoader.loadDependencies(info);
                     if (result.error() != null && result.entries().isEmpty()) {
-                        applyResult(Collections.emptyList(), result.error());
+                        applyResult(Collections.emptyList(), null, 
result.error());
                         return;
                     }
                     appArtifacts = new HashSet<>();
@@ -433,22 +464,22 @@ class CatalogTab extends AbstractTableTab {
                     }
                 }
 
-                CamelCatalog catalog = CatalogLoader.loadCatalog(null, 
info.camelVersion, true);
-                if (catalog == null) {
-                    applyResult(Collections.emptyList(), "Could not load 
catalog for version " + info.camelVersion);
+                CamelCatalog cat = CatalogLoader.loadCatalog(null, 
info.camelVersion, true);
+                if (cat == null) {
+                    applyResult(Collections.emptyList(), null, "Could not load 
catalog for version " + info.camelVersion);
                     return;
                 }
 
                 List<CatalogEntry> entries = new ArrayList<>();
-                collectArtifacts(catalog, "component", 
catalog.findComponentNames(), appArtifacts, entries);
-                collectArtifacts(catalog, "dataformat", 
catalog.findDataFormatNames(), appArtifacts, entries);
-                collectArtifacts(catalog, "language", 
catalog.findLanguageNames(), appArtifacts, entries);
-                collectArtifacts(catalog, "other", catalog.findOtherNames(), 
appArtifacts, entries);
+                collectArtifacts(cat, "component", cat.findComponentNames(), 
appArtifacts, entries);
+                collectArtifacts(cat, "dataformat", cat.findDataFormatNames(), 
appArtifacts, entries);
+                collectArtifacts(cat, "language", cat.findLanguageNames(), 
appArtifacts, entries);
+                collectArtifacts(cat, "other", cat.findOtherNames(), 
appArtifacts, entries);
 
                 entries.sort((a, b) -> a.name.compareToIgnoreCase(b.name));
-                applyResult(entries, null);
+                applyResult(entries, cat, null);
             } catch (Exception e) {
-                applyResult(Collections.emptyList(), "Error: " + 
e.getMessage());
+                applyResult(Collections.emptyList(), null, "Error: " + 
e.getMessage());
             } finally {
                 loading.set(false);
             }
@@ -499,12 +530,13 @@ class CatalogTab extends AbstractTableTab {
         }
     }
 
-    private void applyResult(List<CatalogEntry> entries, String error) {
+    private void applyResult(List<CatalogEntry> entries, CamelCatalog cat, 
String error) {
         if (ctx.runner == null) {
             return;
         }
         ctx.runner.runOnRenderThread(() -> {
             allEntries = entries;
+            catalog = cat;
             errorMessage = error;
             dataLoaded = true;
             refilter();
@@ -613,12 +645,20 @@ class CatalogTab extends AbstractTableTab {
                 Press `/` to open the filter input. Type a search term and 
press
                 `Enter` to filter by substring match on name, title, or label.
 
+                ## Documentation
+
+                Press `d` to open the full documentation for the selected 
artifact in
+                a scrollable viewer. The documentation is loaded from the 
Camel catalog
+                and converted from AsciiDoc to Markdown. Use 
`↑`/`↓`/`PgUp`/`PgDn` or
+                mouse scroll to navigate, and `Esc` to close.
+
                 ## Keys
 
                 - `s` — cycle sort column (name, kind, description)
                 - `S` — reverse sort order
                 - `a` — toggle app only / full catalog
                 - `f` — cycle scope
+                - `d` — open documentation viewer
                 - `/` — open filter
                 - `Esc` — clear filter or back
                 """;
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 e298e7664358..622f0377fa95 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
@@ -41,6 +41,7 @@ class MonitorContext {
     boolean logPinVisible;
     boolean ratePerMinute;
     BiConsumer<String, Boolean> notificationCallback;
+    BiConsumer<String, String> openMarkdownCallback;
 
     MonitorContext(
                    AtomicReference<List<IntegrationInfo>> data,

Reply via email to