Skip to content

CAMEL-23720: Add emoji icons to camel-jbang TUI tab headers and centralize glyphs#24412

Open
ammachado wants to merge 2 commits into
apache:mainfrom
ammachado:CAMEL-23720
Open

CAMEL-23720: Add emoji icons to camel-jbang TUI tab headers and centralize glyphs#24412
ammachado wants to merge 2 commits into
apache:mainfrom
ammachado:CAMEL-23720

Conversation

@ammachado

@ammachado ammachado commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

Description

Adds emoji icons to the camel-jbang-plugin-tui monitor and centralizes all glyph handling:

  • Introduce TuiIcons as the single source of truth for emoji and UI symbols. Add icons to every primary tab header, the More submenu, and the Go to… popup; replace hardcoded footer navigation hints (↑↓, ↑↓←→, etc.) with TuiIcons constants.
  • Consolidate the More submenu into a single TabRegistry.MoreTab record (icon, name, label, tab), replacing the fragile parallel arrays and the MORE_TAB_KEY_INDEX offset table. PopupManager, McpFacade, and ActionsPopup now read from this one list.
  • Derive keyboard shortcuts from Windows-style & mnemonic markers embedded in each label, so the underline offset and the trigger key can no longer drift apart. This fixes the Browse/Configuration mis-highlight where the wrong letter was underlined. Mnemonic triggers are case-insensitive (w and W both fire).
  • Render the primary tab bar compact everywhere with two spaces between the emoji and the key digit, and give the Route/Top cells equal width so toggling Top mode no longer shifts the bar. TABS_FULL_MIN_WIDTH (157) now only selects tight vs spaced dividers.
  • Icons use plain 2-column emoji without VS16 variation selectors (CAMEL-23818) to avoid width artifacts. PROD_PROFILE is 📦 (matching the current main glyph), not the padlock 🔒.

Hardening of the MoreTab model:

  • Add a compact constructor to MoreTab that validates the & mnemonic marker, so a malformed label fails loudly at construction with the offending label instead of throwing StringIndexOutOfBounds from shortcut() during the eager allTabEntries() call at startup.
  • Replace the last hardcoded More index (selectMoreTab(12)) with a name lookup via a new moreTabIndex("SQL Query"), removing the final piece of index coupling the refactor left behind.
  • Make PRIMARY_TAB_ICONS an unmodifiable List (was a mutable array) and drop TuiIcons to package-private to match its members.

Remaining glyph centralization (addresses review feedback):

  • Migrate raw emoji literals that lived in the popup/browser classes to TuiIcons: ExampleBrowserPopup (bundled/online/Docker/infra/Citrus icons and legend), InfraBrowserPopup (service row prefix), and FolderBrowser (directory icon).
  • DoctorPopup MCP connection check now uses TuiIcons.MCP instead of reusing TuiIcons.OTEL (which stays for OTel Spans).

Tests: TuiIconsTest, TabBarRenderTest, and a registry-backed TabRegistryTest guard icon width, mnemonic/shortcut derivation, the Browse/Configuration regression, Route/Top width parity, and case-insensitive triggers. A tautological shortcut test (it re-derived shortcut(), so it could not fail) is replaced with a literal historical-sequence oracle (B,W,C,A,G,N,D,H,I,M,K,E,Q,R,O,P,S,T), with added coverage for shortcut uniqueness, the constructor validation, moreTabIndex, allTabEntries, and PRIMARY_TAB_ICONS ordering. The camel-jbang-plugin-tui module test suite passes (the two ThemeTest/OverviewTabRenderTest flakes are pre-existing on main, caused by order-dependent Theme static state).

Target

  • I checked that the commit is targeting the correct branch (Camel 4 uses the main branch)

Tracking

  • If this is a large change, bug fix, or code improvement, I checked there is a JIRA issue filed for the change (usually before you start working on it).

Apache Camel coding standards and style

  • I checked that each commit in the pull request has a meaningful subject line and body.
  • I have run mvn clean install -DskipTests locally from root folder and I have committed all auto-generated changes.

AI-assisted contributions

  • If this PR includes AI-generated code, commits have proper co-authorship attribution (e.g., Co-authored-by trailers) and the PR description identifies the AI tool used.

AI-generated PR description on behalf of Adriano Machado, via Claude Code.

@github-actions

github-actions Bot commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

🌟 Thank you for your contribution to the Apache Camel project! 🌟
🤖 CI automation will test this PR automatically.

🐫 Apache Camel Committers, please review the following items:

  • First-time contributors require MANUAL approval for the GitHub Actions to run
  • You can use the command /component-test (camel-)component-name1 (camel-)component-name2.. to request a test from the test bot although they are normally detected and executed by CI.
  • You can label PRs using skip-tests and test-dependents to fine-tune the checks executed by this PR.
  • Build and test logs are available in the summary page. Only Apache Camel committers have access to the summary.

⚠️ Be careful when sharing logs. Review their contents before sharing them publicly.

@github-actions github-actions Bot added the dsl label Jul 3, 2026
@github-actions

github-actions Bot commented Jul 4, 2026

Copy link
Copy Markdown
Contributor

🧪 CI tested the following changed modules:

  • dsl/camel-jbang/camel-jbang-plugin-tui

🔬 Scalpel shadow comparison — Scalpel: 2 tested, 1 compile-only — current: 2 all tested

Maveniverse Scalpel detected 3 affected modules (current approach: 2).

⚠️ Modules only in Scalpel (1)
  • camel-launcher

Skip-tests mode would test 2 modules (1 direct + 1 downstream), skip tests for 1 (generated code, meta-modules)

Modules Scalpel would test (2)
  • camel-jbang-plugin-tui
  • camel-launcher-container
Modules with tests skipped (1)
  • camel-launcher

ℹ️ Shadow mode — Scalpel observes but does not affect test execution. Learn more

All tested modules (3 modules)
  • Camel :: JBang :: Plugin :: TUI
  • Camel :: Launcher
  • Camel :: Launcher :: Container

⚙️ View full build and test results

@ammachado ammachado changed the title CAMEL-23720: Add emoji icons to camel-jbang TUI tab headers and centralize glyphs [WIP] CAMEL-23720: Add emoji icons to camel-jbang TUI tab headers and centralize glyphs Jul 4, 2026
@ammachado ammachado changed the title [WIP] CAMEL-23720: Add emoji icons to camel-jbang TUI tab headers and centralize glyphs CAMEL-23720: Add emoji icons to camel-jbang TUI tab headers and centralize glyphs Jul 4, 2026
@ammachado ammachado marked this pull request as ready for review July 4, 2026 04:03

@davsclaus davsclaus left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review: CAMEL-23720 — Add emoji icons to TUI tab headers and centralize glyphs

Well-structured refactoring across 5 commits. TuiIcons as single source of truth, MoreTab record consolidation, and mnemonic-derived shortcuts are all sound. Excellent test coverage (icon width, VS16 absence, shortcut uniqueness, historical sequence oracle, Browse/Configuration regression guard).

Minor suggestions (non-blocking)

  1. TuiHelper.fileEmoji() / fileEmojiByName() still return raw emoji literalsFilesBrowser.fileType() now switches on TuiIcons constants, but the methods producing the values it compares against haven't been migrated. Works because the values are identical, but contradicts the "single source of truth" principle this PR establishes. Good follow-up candidate.

  2. VS16 in some constantsDEV_PROFILE = "🛠️" and WARN = "⚠️" contain VS16 (U+FE0F), while the class Javadoc and CAMEL-23818 reference say to avoid it. The primaryTabEmojisHaveNoVariationSelector test only checks PRIMARY_TAB_ICONS. These were pre-existing values; consider cleaning them up or documenting as exceptions.

  3. Icon alias namingTuiIcons.OTEL (🔗) is reused for MCP connection doctor checks (not OTel-related), and TAB_STARTUP reuses QUARKUS (🚀) though Startup isn't Quarkus-specific. Naming nitpicks, not bugs.

None of these are blocking. Nice contribution!


This review does not replace specialized tools such as CodeRabbit, Sourcery, or SonarCloud.

This review was generated by an AI agent and may contain inaccuracies. Please verify all suggestions before applying.


// ---- Brand & runtime ----
static final String CAMEL = "🐪";
static final String SPRING_BOOT = "🍃";

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor: DEV_PROFILE = "🛠️" and WARN = "⚠️" (lines 35, 39) contain VS16 variation selectors, while the class Javadoc says to use "plain 2-column-wide emoji without VS16". The primaryTabEmojisHaveNoVariationSelector test only checks PRIMARY_TAB_ICONS. These were pre-existing values being centralized — consider either stripping VS16 or adding a doc note that these are intentional exceptions.

@@ -117,7 +117,7 @@ private boolean loadDirectory(Path dir) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The switch in fileType() (line 315) now matches against TuiIcons.CAMEL, TuiIcons.JAVA, etc., but TuiHelper.fileEmoji() which produces the values being compared still returns raw emoji literals. Works because the values are identical, but a follow-up migrating TuiHelper.fileEmoji()/fileEmojiByName() to use TuiIcons would complete the centralization.

ammachado and others added 2 commits July 4, 2026 14:13
Introduce TuiIcons as the single source of truth for emoji and UI
symbols across the camel-jbang TUI: tab bar, More submenu, footer
navigation hints, and the F2 Actions/Go-to popups. Consolidate the
More submenu into a MoreTab record with & mnemonics, add a compact
tab-bar threshold, and strengthen TUI icon tests (TuiIconsTest,
tab bar render tests) validating icon width constraints and
MoreTab invariants.

Co-authored-by: Cursor <cursoragent@cursor.com>
Migrate raw emoji literals that lived in popup/browser classes to the
TuiIcons registry, completing the single-source-of-truth goal:

- ExampleBrowserPopup: bundled/online/Docker/infra/Citrus icons and legend
- InfraBrowserPopup: infra service row prefix
- FolderBrowser: directory icon
- DoctorPopup: MCP connection check now uses TuiIcons.MCP instead of
  reusing TuiIcons.OTEL (which stays for OTel Spans)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants