Skip to content

feat(reborn): unify visible dropdown menus - #5940

Merged
think-in-universe merged 8 commits into
mainfrom
issue-5938-select-menu-unification
Jul 13, 2026
Merged

think-in-universe merged 8 commits into
mainfrom
issue-5938-select-menu-unification

Conversation

@italic-jinxin

Copy link
Copy Markdown
Contributor

Summary

  • Replaces visible Reborn native dropdowns with the shared SelectMenu in Slack channel routing, LLM provider configuration, and admin user role controls.
  • Preserves existing selected values, disabled states, placeholders, option ordering, and change handlers while aligning dropdown styling with the shared menu component.
  • Updates focused frontend tests for the Slack channel picker and provider model selection comments.

Linked Issue

Closes #5938

Validation

  • pnpm run typecheck
  • pnpm vitest run src/design-system/select-menu.test.ts src/components/slack-channel-picker.test.ts src/pages/settings/components/provider-components.test.ts src/pages/settings/components/inference-tab.test.ts src/pages/settings/lib/llm-providers.test.ts
  • TZ=UTC pnpm test
  • pnpm run build
  • git diff --check

Security Impact

No. This is a client-side UI component migration only.

Database Impact

No schema or persistence changes.

Blast Radius

Limited to visible Reborn dropdown controls in Extensions channel setup, Settings LLM provider configuration, and Admin user role management.

Rollback Plan

Revert this PR to restore the previous native dropdown controls for these visible surfaces.

@italic-jinxin italic-jinxin added size: M 50-199 changed lines risk: low Changes to docs, tests, or low-risk modules contributor: core 20+ merged PRs labels Jul 10, 2026
@ironloopai

ironloopai Bot commented Jul 10, 2026 •

Copy link
Copy Markdown
Contributor

🔎 IronLoop Review Status

Head: 6448fdb3886f9bd7dd2a8a884d90bb5885192740
Result: One or more review results were superseded by a newer PR head.
Next: Run @ironloopai review on the latest PR head.
Updated: 2026-07-10T14:12:02.189Z

Current reviewers:

Reviewer State Verdict Findings Last update
ironloop/common-reviewer (reviewer) Superseded N/A N/A 2026-07-10T14:06:42.478Z
Reviewer summaries
Reviewer Detail
ironloop/common-reviewer (reviewer) Superseded by a newer PR head. New head: 53a1e9d. Previous verdict: Changes requested.
Recent activity
Time Reviewer State Detail
2026-07-10T13:58:58.781Z ironloop/common-reviewer (reviewer) Queued Waiting for this reviewer lane to become available.
2026-07-10T13:58:58.938Z ironloop/common-reviewer (reviewer) Queued Added to the local review work handoff.
2026-07-10T13:59:00.062Z ironloop/common-reviewer (reviewer) Started Reviewer worker started attempt 1.
2026-07-10T13:59:03.474Z ironloop/common-reviewer (reviewer) Workspace ready Prepared isolated checkout (merge_ref) at 8276b5c.
2026-07-10T14:03:21.307Z ironloop/common-reviewer (reviewer) Superseded Old-head reviewer is still running after newer head 53a1e9d replaced it. Codex is reviewing; process live; elapsed 4m 19s; timeout in 15m 41s; last heartbeat 2026-07-10T14:03:21.307Z. Codex emitted stderr output at 2026-07-10T14:02:42.192Z.
2026-07-10T14:03:24.688Z ironloop/common-reviewer (reviewer) Result captured Changes requested; 1 blocking finding.
2026-07-10T14:03:24.688Z ironloop/common-reviewer (reviewer) Completed Review completed and terminal status was persisted.
2026-07-10T14:06:42.478Z ironloop/common-reviewer (reviewer) Superseded A newer PR head replaced this review (53a1e9d).
Available commands
  • @ironloopai help
  • @ironloopai agents
  • @ironloopai review
  • @ironloopai review --agent <agent>
  • @ironloopai status
Run metadata

Admission: webhook accepted the request and IronLoop persisted reviewer state before this projection.

@coderabbitai

coderabbitai Bot commented Jul 10, 2026 •

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 6036d730-7098-42cd-8ac4-a3b795c59c5d

📥 Commits

Reviewing files that changed from the base of the PR and between 53a1e9d and 6448fdb.

📒 Files selected for processing (4)
  • crates/ironclaw_webui_v2/frontend/src/pages/admin/components/user-detail.tsx
  • crates/ironclaw_webui_v2/frontend/src/pages/admin/components/users-tab.tsx
  • crates/ironclaw_webui_v2/frontend/src/pages/admin/lib/admin-presenters.ts
  • tests/e2e/scenarios/test_reborn_webui_v2_legacy_settings_search.py

📝 Walkthrough

Summary by CodeRabbit

  • UI Improvements

    • Updated channel subject, admin user role, user creation role, and provider adapter/model selectors to use the shared SelectMenu component.
    • Enhanced provider model dropdown to preserve a typed default value when it isn’t in fetched options.
    • Improved accessibility labeling for channel subject selectors and updated related selector rendering.
  • Behavior & Accessibility

    • Refined SelectMenu Escape handling to stop event propagation while closing an open menu.
  • Tests

    • Updated end-to-end flows to select options via a dedicated SelectMenu interaction helper.
    • Strengthened SelectMenu and channel picker tests with improved accessibility/rendering assertions.
  • Documentation

    • Updated SelectMenu-related comments to reflect the controlled component behavior.

Walkthrough

Reborn dropdowns in Slack, administration, and provider settings now use the shared SelectMenu component. Option generation, accessibility labels, typed model handling, Escape behavior, test stubs, comments, and Playwright interactions were updated.

Changes

SelectMenu migration

Layer / File(s) Summary
Slack subject selectors
crates/ironclaw_webui_v2/frontend/src/components/slack-channel-picker.tsx, crates/ironclaw_webui_v2/frontend/src/components/slack-channel-picker.test.ts
Draft and per-channel subject controls use memoized SelectMenu options, channel-specific ARIA labels, and updated rendering assertions.
Admin role selectors
crates/ironclaw_webui_v2/frontend/src/pages/admin/components/user-detail.tsx, crates/ironclaw_webui_v2/frontend/src/pages/admin/components/users-tab.tsx, crates/ironclaw_webui_v2/frontend/src/pages/admin/lib/admin-presenters.ts
User detail and creation role controls use translated, memoized options with SelectMenu state wiring.
Provider settings selectors
crates/ironclaw_webui_v2/frontend/src/pages/settings/components/provider-dialog.tsx, crates/ironclaw_webui_v2/frontend/src/pages/settings/hooks/useProviderDialogForm.ts, crates/ironclaw_webui_v2/frontend/src/pages/settings/lib/llm-providers*, tests/e2e/scenarios/test_reborn_webui_v2_legacy_settings_search.py
Adapter and model controls use SelectMenu; typed model values are retained in options, and E2E tests select menu entries through a shared helper.
Escape event handling
crates/ironclaw_webui_v2/frontend/src/design-system/select-menu.tsx, crates/ironclaw_webui_v2/frontend/src/design-system/select-menu.test.ts
Open-menu Escape handling now stops propagation, with tests covering closed and open states.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Admin as Admin user
  participant ProviderDialog
  participant SelectMenu
  participant FormState
  Admin->>ProviderDialog: Open provider dialog
  ProviderDialog->>SelectMenu: Render adapter and model options
  Admin->>SelectMenu: Choose an option
  SelectMenu->>FormState: Return selected value
  FormState->>ProviderDialog: Update form.adapter or form.model
Loading
🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title uses conventional-commit style and accurately summarizes the SelectMenu dropdown migration.
Description check ✅ Passed The description covers summary, linked issue, validation, security, DB impact, blast radius, and rollback; only some optional sections are omitted.
Linked Issues check ✅ Passed The PR migrates the targeted Reborn dropdowns to SelectMenu and updates tests, matching #5938's core goals.
Out of Scope Changes check ✅ Passed No clear unrelated changes are present; the comment/test updates and SelectMenu keyboard fix support the dropdown migration.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@railway-app
railway-app Bot temporarily deployed to ironclaw-ci-preview / ironclaw-pr-5940 July 10, 2026 13:41 Destroyed
@italic-jinxin

Copy link
Copy Markdown
Contributor Author

@claude review

@gemini-code-assist gemini-code-assist Bot 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.

Code Review

This pull request replaces standard HTML <select> elements and custom <Select> wrappers with a new <SelectMenu> component across several frontend components, including the Slack channel picker, user detail panel, user creation form, and LLM provider dialog. Feedback focuses on improving the user experience and accessibility: first, by dynamically appending custom model values to the SelectMenu options in the provider dialog to prevent UI mismatches; second, by appending the channel ID to the ariaLabel of each dropdown in the Slack channel picker list to improve screen reader accessibility.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment thread crates/ironclaw_webui_v2/frontend/src/components/slack-channel-picker.tsx Outdated
@claude

This comment was marked as resolved.

@railway-app
railway-app Bot temporarily deployed to ironclaw-ci-preview / ironclaw-pr-5940 July 10, 2026 13:46 Destroyed
@railway-app
railway-app Bot temporarily deployed to ironclaw-ci-preview / ironclaw-pr-5940 July 10, 2026 13:52 Destroyed
@italic-jinxin
italic-jinxin marked this pull request as ready for review July 10, 2026 13:58
@github-actions

github-actions Bot commented Jul 10, 2026 •

Copy link
Copy Markdown
Contributor

Coverage ratchet

Ratchet mode: ENFORCING

RATCHET PASS: global
  observed: 85.26% (292830 / 343446 lines)
  floor:    85.3% (tolerance 0.5pp -> effective floor 84.8%)
  denominator: 343446 lines now vs 320188 at floor capture (+23258 lines, +7.26%) — material change (>5%)

⚠️ 2 Reborn crate(s) have 0 int-tier coverage (target: 0) — ironclaw_prompt_envelope, ironclaw_scripts

Reborn integration-tier coverage

Line coverage (Reborn crates): 85.26% — 292830 / 343446 lines

Per-crate breakdown (63 crates, lowest-covered first)
Crate Line % Covered / Total
ironclaw_prompt_envelope 0% 0 / 88
ironclaw_scripts 0% 0 / 345
ironclaw_runtime_policy 31.75% 80 / 252
ironclaw_event_projections 43.31% 673 / 1554
ironclaw_run_state 52.36% 222 / 424
ironclaw_authorization 53.66% 462 / 861
ironclaw_triggers 59.89% 1792 / 2992
ironclaw_observability 61.54% 16 / 26
ironclaw_webui_v2 62.76% 2659 / 4237
ironclaw_reborn_cli 62.88% 3851 / 6124
ironclaw_mcp 63.03% 578 / 917
ironclaw_reborn_migration 67.09% 1215 / 1811
ironclaw_filesystem 67.1% 3833 / 5712
ironclaw_dispatcher 67.15% 92 / 137
ironclaw_memory 69.2% 773 / 1117
ironclaw_trust 72.88% 661 / 907
ironclaw_capabilities 74.39% 1685 / 2265
ironclaw_wasm_limiter 74.6% 47 / 63
ironclaw_reborn_event_store 74.67% 958 / 1283
ironclaw_extractors 74.72% 538 / 720
ironclaw_first_party_extensions 77.66% 5400 / 6953
ironclaw_llm 78.32% 20260 / 25869
ironclaw_product_context 78.57% 11 / 14
ironclaw_process_sandbox 80.65% 671 / 832
ironclaw_wasm_product_adapters 80.71% 1448 / 1794
ironclaw_reborn_openai_compat 81.16% 978 / 1205
ironclaw_memory_native 81.22% 3205 / 3946
ironclaw_secrets 82.7% 2791 / 3375
ironclaw_wasm 82.72% 996 / 1204
ironclaw_events 82.86% 1765 / 2130
ironclaw_auth 83.87% 3078 / 3670
ironclaw_reborn_config 84.33% 1814 / 2151
ironclaw_processes 84.44% 993 / 1176
ironclaw_turns 84.66% 13447 / 15884
ironclaw_common 84.85% 1490 / 1756
ironclaw_host_api 85.17% 2664 / 3128
ironclaw_product_workflow 85.56% 10836 / 12665
ironclaw_projects 85.92% 659 / 767
ironclaw_threads 86.04% 4234 / 4921
ironclaw_network 86.12% 670 / 778
ironclaw_slack_v2_adapter 86.79% 1806 / 2081
ironclaw_product_adapters 86.98% 3207 / 3687
ironclaw_reborn_identity 87.03% 557 / 640
ironclaw_skills 87.6% 4471 / 5104
ironclaw_hooks 87.75% 9917 / 11302
ironclaw_product_adapter_registry 88.06% 531 / 603
ironclaw_reborn_traces 88.19% 11946 / 13546
ironclaw_host_runtime 88.41% 17188 / 19442
ironclaw_extensions 89.03% 2864 / 3217
ironclaw_reborn_composition 89.04% 76204 / 85582
ironclaw_approvals 89.24% 1584 / 1775
ironclaw_runner 89.29% 16694 / 18697
ironclaw_conversations 90.33% 3120 / 3454
ironclaw_event_streams 90.82% 1009 / 1111
ironclaw_loop_support 92.51% 14752 / 15947
ironclaw_resources 92.83% 4736 / 5102
ironclaw_attachments 93.06% 630 / 677
ironclaw_reborn_webui_ingress 93.19% 2217 / 2379
ironclaw_telegram_v2_adapter 93.62% 2511 / 2682
ironclaw_agent_loop 94.66% 8771 / 9266
ironclaw_safety 94.88% 3671 / 3869
ironclaw_first_party_extension_ports 95.24% 3343 / 3510
ironclaw_outbound 95.59% 3556 / 3720

This table itself is informational and never gates the PR on its own — not the percentage, not the per-crate holes, not the 0-coverage callout. A separate coverage ratchet (dry-run until enforce=true; see tests/integration/coverage-floor.toml) can fail the build on specific configured floors.

Exemptions (3 entry/entries excluded from the accounting above)
Module / Crate Reason Issue
crate: ironclaw_embeddings v1-only: consumed only by root ironclaw (src/app.rs, src/tools/builtin/memory.rs, src/workspace/mod.rs, src/config/{mod,embeddings}.rs); no crates/* dependents. Covered by "Tests (Legacy)". #5657
crate: ironclaw_gateway v1-only: consumed only by root ironclaw (src/channels/web/platform/static_files.rs, src/channels/web/handlers/frontend.rs); no crates/* dependents. Covered by "Tests (Legacy)". #5657
crate: ironclaw_tui v1-only: consumed only by root ironclaw (src/main.rs, src/channels/tui.rs); no crates/* dependents. Crate's own doc comment confirms it bridges INTO v1, not Reborn. Covered by "Tests (Legacy)". #5657

ironloopai[bot]

This comment was marked as resolved.

@railway-app
railway-app Bot temporarily deployed to ironclaw-ci-preview / ironclaw-pr-5940 July 10, 2026 14:06 Destroyed

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@crates/ironclaw_webui_v2/frontend/src/pages/admin/components/user-detail.tsx`:
- Around line 30-35: Move the duplicated buildRoleOptions function from
user-detail.tsx and users-tab.tsx into the shared admin-presenters module
alongside formatUserRole and roleTone, export it there, and update both
components to import and use the shared helper. Remove both local definitions.

In `@tests/e2e/scenarios/test_reborn_webui_v2_legacy_settings_search.py`:
- Line 327: Add the missing -> None return type annotation to the
_choose_select_menu_option function, matching the existing annotation style such
as _mock_llm_state and satisfying Ruff ANN202.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: ffe16109-7d50-4dd5-b5b8-042d983d8d78

📥 Commits

Reviewing files that changed from the base of the PR and between 7330422 and 6d888c3.

📒 Files selected for processing (9)
  • crates/ironclaw_webui_v2/frontend/src/components/slack-channel-picker.test.ts
  • crates/ironclaw_webui_v2/frontend/src/components/slack-channel-picker.tsx
  • crates/ironclaw_webui_v2/frontend/src/pages/admin/components/user-detail.tsx
  • crates/ironclaw_webui_v2/frontend/src/pages/admin/components/users-tab.tsx
  • crates/ironclaw_webui_v2/frontend/src/pages/settings/components/provider-dialog.tsx
  • crates/ironclaw_webui_v2/frontend/src/pages/settings/hooks/useProviderDialogForm.ts
  • crates/ironclaw_webui_v2/frontend/src/pages/settings/lib/llm-providers.test.ts
  • crates/ironclaw_webui_v2/frontend/src/pages/settings/lib/llm-providers.ts
  • tests/e2e/scenarios/test_reborn_webui_v2_legacy_settings_search.py

Comment thread crates/ironclaw_webui_v2/frontend/src/pages/admin/components/user-detail.tsx Outdated
Comment thread tests/e2e/scenarios/test_reborn_webui_v2_legacy_settings_search.py Outdated
@railway-app

railway-app Bot commented Jul 10, 2026 •

Copy link
Copy Markdown

🚅 Deployed to the ironclaw-pr-5940 environment in ironclaw-ci-preview

Service Status Web Updated (UTC)
ironclaw ✅ Success (View Logs) Web Jul 11, 2026 at 2:55 pm

@railway-app
railway-app Bot temporarily deployed to ironclaw-ci-preview / ironclaw-pr-5940 July 10, 2026 14:12 Destroyed
@railway-app
railway-app Bot temporarily deployed to ironclaw-ci-preview / ironclaw-pr-5940 July 11, 2026 07:37 Destroyed
@railway-app
railway-app Bot temporarily deployed to ironclaw-ci-preview / ironclaw-pr-5940 July 11, 2026 13:11 Destroyed
@railway-app
railway-app Bot temporarily deployed to ironclaw-ci-preview / ironclaw-pr-5940 July 11, 2026 14:45 Destroyed
@italic-jinxin italic-jinxin self-assigned this Jul 12, 2026
@think-in-universe
think-in-universe added this pull request to the merge queue Jul 13, 2026
Merged via the queue into main with commit 0815220 Jul 13, 2026
62 checks passed
@think-in-universe
think-in-universe deleted the issue-5938-select-menu-unification branch July 13, 2026 10:19

This branch was successfully deployed

No deployments
ironclaw-ci-preview / ironclaw-pr-5940 — 1b73266d Deployed Jul 11, 2026 by railway-app[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

contributor: core 20+ merged PRs risk: low Changes to docs, tests, or low-risk modules size: M 50-199 changed lines

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Unify Reborn dropdown styling with the shared SelectMenu component

2 participants