Skip to content

Quick actions refactor + new features#3131

Open
david-crespo wants to merge 10 commits intomainfrom
quick-actions-refactor
Open

Quick actions refactor + new features#3131
david-crespo wants to merge 10 commits intomainfrom
quick-actions-refactor

Conversation

@david-crespo
Copy link
Collaborator

@david-crespo david-crespo commented Mar 17, 2026

#3129 inspired me to add a couple more features to the quick actions menu, which in turn inspired a big refactor to avoid problems with possible duplicate entries. I also added a bunch of e2e tests that we probably should have had before.

New features

  • ctrl+n/ctrl+p keyboard navigation (in addition to arrow keys)
  • "Go up" actions derived from breadcrumbs, so you can quickly navigate to parent pages
  • Links are real links, which means you can middle click them if you insist
2026-03-17-quick-actions-breadcrumbs.mp4

Refactor

The old store held a flat list of QuickActionItem.

export interface QuickActionItem {
value: string
// strings are paths to navigate() to
// onSelect: string | (() => void)
onSelect: () => void
navGroup?: string
}

value there is the text label displayed in the UI and (problematically) is also meant to uniquely identify the item. When calling pages (e.g., the project layout and the instance list page) called useQuickActions with a list of items, useQuickActions called addActions, which deduped the list of items based on value. The problem is that items with the same value in different groups could collide — removing by value would remove items you didn't meant to remove. We had an invariant call making sure the values were unique, but this is actually pretty bad in hindsight because it's probably possible for a user to name something to create a duplicate. (In practice we probably avoided this because all user-settable names are lower-case and all our nav items have upper case letters.)

In any case, the new breadcrumbs feature added a new source of items that could potentially be a duplicate with something else in the list. That is what prompted me to get rid of the deduping mechanism altogether. The new store is a Map<string, QuickActionItem[]> keyed by an ID for each calling page, so registration is just map.set(id, items) and cleanup is map.delete(id). Deduping is unnecessary because each source component owns its own slot. In theory each source is responsible for deduping its items, but the way the item lists are constructed, this is never really a problem. And if a duplicate sneaks in, it doesn't actually matter.

Finally, since I was already messing everything up, I changed QuickActionItem to take both link and callback items, like we do for menu items. They're almost all links — only a few modal-opening actions are not.

@vercel
Copy link

vercel bot commented Mar 17, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
console Ready Ready Preview Mar 18, 2026 2:55am

Request Review

@david-crespo
Copy link
Collaborator Author

Bad sign for flakiness, will investigate.

image

@david-crespo
Copy link
Collaborator Author

Autofocus worked to get rid of the flake in the new tests, now we're just left with existing flakiness.

image

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