Skip to content

feat: implement WordPress Command Palette to replace Jumper navigation (#474)#477

Merged
superdav42 merged 1 commit intomainfrom
feat/474-command-palette
Mar 25, 2026
Merged

feat: implement WordPress Command Palette to replace Jumper navigation (#474)#477
superdav42 merged 1 commit intomainfrom
feat/474-command-palette

Conversation

@superdav42
Copy link
Copy Markdown
Collaborator

Summary

Implements the WordPress Command Palette (⌘K / Ctrl+K) as a replacement for the legacy Jumper navigation widget. The Command Palette provides quick access to all WP Ultimo entities, admin pages, settings, and custom links via the native WordPress command palette API (available since WordPress 6.4).

This is a clean reimplementation based on the closed WIP PR #285, with all CodeRabbit review findings addressed upfront.

What was built

Component Description
inc/ui/class-command-palette-manager.php Singleton manager: enqueues JS, passes config via wp_localize_script, registers settings section
inc/apis/trait-command-palette.php Trait added to all 10 entity managers; registers each entity type and provides search/format methods
inc/apis/class-command-palette-rest-controller.php REST endpoint at ultimate-multisite/v1/command-palette/search
assets/js/command-palette.js Registers dynamic search loader (debounced, cached, 2-char minimum), static commands, and custom links
10 entity managers Added use Command_Palette trait + enable_command_palette() call
inc/class-wp-ultimo.php Loads Command_Palette_Manager + Command_Palette_Rest_Controller instead of Jumper::get_instance()

CodeRabbit fixes applied (from PR #285 review)

  • JS: slug.replace('_', '-')slug.replace(/_/g, '-') to handle multi-underscore slugs (e.g. checkout_formcheckout-forms)
  • REST controller: Removed strict bool return type from search_permissions_check() — actual return is bool|\WP_Error per WP REST API convention
  • REST controller: foreach ($entities as $slug => $config)foreach (array_keys($entities) as $slug) to avoid unused $config variable

Design decisions

  • Jumper files preserved: jumper.css, jumper.js, class-jumper.php are kept but no longer loaded. The AJAX search handlers in class-ajax.php (search_models, render_selectize_templates) are intentionally preserved — selectizer.js and tax-rates.js depend on them for selectize dropdowns throughout the admin.
  • Version-gated: Requires WordPress 6.4+ (checked server-side); JavaScript uses feature detection (wp.commands availability check) for graceful degradation.
  • Capability: Requires manage_network — network admins only.
  • Settings: Reuses the existing jumper_custom_links setting key for backward compatibility with existing custom link configurations.

Testing

  1. Open any WP Ultimo admin page on WordPress 6.4+
  2. Press Ctrl+K (or Cmd+K on Mac) to open the Command Palette
  3. Type a customer name, site domain, or product name — results appear with debounce
  4. Static commands: "Ultimate Multisite Dashboard", "Ultimate Multisite Settings", "System Information", entity list pages
  5. Custom links: add entries in Settings → Tools → Command Palette

Closes #474
Ref: PR #285 (closed WIP)

Replaces the legacy Jumper quick-navigation widget with the native
WordPress Command Palette (Ctrl/Cmd+K), available since WordPress 6.4.

## What was built

- Command_Palette_Manager (inc/ui/): singleton that gates on WP 6.4+,
  enqueues command-palette.js, localises config (entities, REST URL,
  nonce, custom links), and registers a 'Tools > Command Palette' settings
  section reusing the existing jumper_custom_links setting.

- Command_Palette trait (inc/apis/): added to all 10 entity managers
  (broadcast, checkout_form, customer, discount_code, domain, membership,
  payment, product, site, webhook). Each manager calls
  enable_command_palette() in init(), which registers the entity with the
  manager on the 'init' hook.

- Command_Palette_Rest_Controller (inc/apis/): REST endpoint at
  ultimate-multisite/v1/command-palette/search. Requires manage_network
  capability. Searches all registered entity types (or a specific one via
  entity_type param), applies wu_command_palette_search_results filter.

- command-palette.js: registers a dynamic command loader (useEntitySearch
  hook with 300ms debounce, 2-char minimum, result caching) plus static
  commands for the dashboard, settings, system info, entity list pages,
  and custom links. Uses wp.commands, wp.element, wp.apiFetch.

- class-wp-ultimo.php: loads Command_Palette_Manager and
  Command_Palette_Rest_Controller instead of Jumper::get_instance().

## CodeRabbit fixes applied

- slug.replace('_', '-') → slug.replace(/_/g, '-') to handle multi-
  underscore slugs (e.g. checkout_form → checkout-forms).
- search_permissions_check(): removed strict bool return type; actual
  return is bool|WP_Error per WP REST API convention.
- foreach ($entities as $slug => $config): changed to
  foreach (array_keys($entities) as $slug) to avoid unused variable.

## Scope

The legacy Jumper UI is no longer loaded. The underlying AJAX search
handlers (search_models, render_selectize_templates) are intentionally
preserved — they are used by selectize dropdowns throughout the admin
and are not Jumper-specific.

Closes #474
Ref: PR #285 (closed WIP)
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Mar 25, 2026

Warning

Rate limit exceeded

@superdav42 has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 12 minutes and 44 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: bf7c5e94-aaa1-45b0-b485-fd0e3f94b3eb

📥 Commits

Reviewing files that changed from the base of the PR and between 13afec2 and 581166a.

📒 Files selected for processing (15)
  • assets/js/command-palette.js
  • inc/apis/class-command-palette-rest-controller.php
  • inc/apis/trait-command-palette.php
  • inc/class-wp-ultimo.php
  • inc/managers/class-broadcast-manager.php
  • inc/managers/class-checkout-form-manager.php
  • inc/managers/class-customer-manager.php
  • inc/managers/class-discount-code-manager.php
  • inc/managers/class-domain-manager.php
  • inc/managers/class-membership-manager.php
  • inc/managers/class-payment-manager.php
  • inc/managers/class-product-manager.php
  • inc/managers/class-site-manager.php
  • inc/managers/class-webhook-manager.php
  • inc/ui/class-command-palette-manager.php
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/474-command-palette

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 and usage tips.

@superdav42
Copy link
Copy Markdown
Collaborator Author

PHP 8.2/8.3/8.5 failures are Docker Hub infrastructure errors (HTTP 500 on cimg/php image pull) — not code issues. CI re-run is in progress.

@github-actions
Copy link
Copy Markdown

🔨 Build Complete - Ready for Testing!

📦 Download Build Artifact (Recommended)

Download the zip build, upload to WordPress and test:

🌐 Test in WordPress Playground (Very Experimental)

Click the link below to instantly test this PR in your browser - no installation needed!
Playground support for multisite is very limitied, hopefully it will get better in the future.

🚀 Launch in Playground

Login credentials: admin / password

@github-actions
Copy link
Copy Markdown

Performance Test Results

Performance test results for ea25604 are in 🛎️!

URL: /

Run DB Queries Memory Before Template Template WP Total LCP TTFB LCP - TTFB
0 57 36.38 MB 296.00 ms 102.00 ms 397.50 ms 485.55 ms 411.55 ms 74.80 ms
1 57 36.38 MB 294.50 ms 101.00 ms 396.00 ms 485.25 ms 409.80 ms 75.10 ms

@superdav42 superdav42 merged commit 23a8fdf into main Mar 25, 2026
16 of 25 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: WordPress Command Palette to replace Jumper navigation (deferred from PR #285)

1 participant