Skip to content

feat(app-admin): command palette (DI-based command registration)#5432

Open
adrians5j wants to merge 8 commits into
release/6.5.0from
command-palette-6.5.0
Open

feat(app-admin): command palette (DI-based command registration)#5432
adrians5j wants to merge 8 commits into
release/6.5.0from
command-palette-6.5.0

Conversation

@adrians5j

Copy link
Copy Markdown
Member

Summary

Adds a ⌘K / Ctrl+K command palette to the Webiny admin app: fuzzy search over navigation destinations and registered actions, keyboard-driven, design-system styled.

Builds on the ideas from #5065 (thanks @Pavel910) — adopting its DI-based command registration and MobX presenter, combined with a design-system UI, navigation derived from the sidebar menus, an in-palette detail view, and working global shortcuts.

What's included

  • DI command registration (@webiny/app-admin): a Command abstraction, a MobX CommandPalettePresenter resolving commands via container.resolveAll(Command), and a CommandPaletteFeature (registered in Admin.tsx, exported from the barrel).
  • Design-system UI (@webiny/app-admin-ui): scrim + panel, grouped list, header "Search or jump to… ⌘K" trigger, breadcrumb sections, ancestor icon inheritance, footer hints — all on DS tokens. Driven by the presenter (observer).
  • Navigation group auto-derived from the registered admin menus (leaf Menu.Links → navigate on select), merged with DI command groups.
  • detailView: a command can render a React form inside the palette; submit runs execute(data). Back returns to the list, Esc closes.
  • Global shortcuts: a command's shortcut registers a working hotkey (useHotkeys gained a [keys] dep for dynamic re-registration).
  • Baseline commands: Copy current URL, Sign out. Plus a demo Send message detail-view command (cmd+shift+m) — flagged, safe to remove.

Registering a command

class MyCommand implements Command.Interface {
  name = "myapp.deploy"; label = "Deploy"; category = "Actions";
  shortcut = "cmd+shift+d";          // optional global hotkey
  execute() { /* ... */ }
  // detailView?: React component rendered inside the palette
}
export const MyCommandImpl = Command.createImplementation({
  implementation: MyCommand, dependencies: [/* DI tokens */]
});
// register inside a feature: container.register(MyCommandImpl)

Notes / follow-ups

  • Ships a demo Send message command (remove the container.register(SendMessageCommand) line to drop it).
  • Deferred: Recent group (route history / ACO), per-module create actions (new entry, publish, upload, invite), automated tests.
  • Known caveat: mod+k shares the useHotkeys zIndex layering — a higher-zIndex layer opened elsewhere can shadow it.

🤖 Generated with Claude Code

adrians5j and others added 8 commits July 17, 2026 14:46
Introduce a Cmd+K / Ctrl+K command palette shell for the admin app,
mounted in AdminUI. Custom scrim+blur overlay wrapping the admin-ui
Command (cmdk) primitive: autofocused input, grouped list, empty state.
Toggled via useHotkeys on a dedicated zIndex layer; closes on Esc and
scrim click.

Phase 1 ships the themed shell with placeholder items only. Navigation
and Actions command sources follow in later phases (see
plans/command-palette.md).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Derive Navigation commands from the registered admin menus: leaf Menu.Link
entries become searchable commands (label, parent-menu section, icon) and
selecting one navigates via RouterGateway.pushState. The palette mounts inside
Layout so it renders within the admin config provider tree.

Rebuild the palette UI on cmdk to match the Webiny design: leading search
icon + esc chip, icon-tile rows with section subtitles, primary-tinted
selection with an "Open" pill, grouped headers, footer hint bar, and a
search_off empty state. Adds cmdk as a direct dependency.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Refactor palette styling onto design-system tokens (Text component,
spacing/radius scale, font weights) instead of hand-picked pixel values;
scrim uses the DS neutral-dark overlay. Leaf navigation items inherit their
parent section's icon (dropping a misleading search-glyph fallback), and the
"Actions" footer hint is removed for now.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add AdminConfig.CommandPalette.Command config API (in @webiny/app-admin,
mirroring Dashboard.Widget) so modules register palette actions declaratively
(name, label, onSelect, group, description, icon, keywords, shortcut,
pin/before/after). Commands surface via useAdminConfig().commands.

The palette now renders grouped Actions alongside Navigation, preserving
registration order; selecting a command runs onSelect and closes. Action rows
support description subtitles and shortcut chips. Split the palette into
focused modules (constants, types, deriveRows, presentational components).
Seeds a demo "Copy current URL" action from AdminUI.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…phase 4/5)

Add a "Search or jump to… ⌘K" trigger to the admin header, backed by a
CommandPaletteProvider so the hotkey and the button share open state.

Register baseline global palette actions (Copy current URL, Sign out) via the
AdminConfig.CommandPalette.Command registry, replacing the earlier demo command.
Richer per-module actions (new entry, publish, upload, invite) remain a
follow-up owned by each module.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Move command registration + palette state to dependency injection (adapted from
Pavel's #5065): a Command DI abstraction, a MobX CommandPalettePresenter resolving
commands via container.resolveAll, and a CommandPaletteFeature. Keeps our design-
system UI (header trigger, breadcrumb sections, ancestor icon inheritance), now
driven by the presenter.

- detailView: a command can render a form inside the palette; submit runs execute(data)
- shortcut: registers a working global hotkey (useHotkeys gains a [keys] dep)
- Global DI commands: Copy current URL, Sign out; demo Send message (detail view)
- Remove the earlier React-config registry (AdminConfig.CommandPalette.Command)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add an example admin extension registering a custom command palette action
via the DI Command abstraction, and expose Command from webiny/admin so
extension authors can import it. Wired (enabled) in webiny.config.tsx.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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.

1 participant