You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
#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
https://github.com/user-attachments/assets/d40d4d80-88b4-41e6-a41b-e7274520fa11
### Refactor
The old store held a flat list of `QuickActionItem`.
https://github.com/oxidecomputer/console/blob/751a80e64b32bacbfc22379e70c24383685cb853/app/ui/lib/ActionMenu.tsx#L22-L28
`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.
0 commit comments