UI and UX improvements to the "Connect an Integration" modal. - #1714
Draft
NWylynko wants to merge 15 commits into
Draft
UI and UX improvements to the "Connect an Integration" modal.#1714NWylynko wants to merge 15 commits into
NWylynko wants to merge 15 commits into
Conversation
The Connect dialog listed every preset flat in a 560px dialog with a fixed
224px scroll area. Two providers contribute 48 of those 85 rows as bare
service names ("Users", "Directory", "Profile"), so the list was mostly
context-free noise and the only way through it was the search box.
- Group each multi-service provider into one card that opens into its
services, so browsing shows 39 cards instead of 85 rows.
- Searching ungroups: typing "outlook" returns the three Outlook services
rather than the Microsoft card they were trying to see past.
- Add protocol facets (All/OpenAPI/MCP/GraphQL) counting the cards each
reveals for the active query.
- Lead with the curated `featured` presets so the providers hiding half the
library are on the first screen rather than row 12.
- Widen the dialog and lay the catalog out in two columns; move the manual
add-by-protocol links to the footer.
Catalog behavior is pure and unit-tested; the dialog moves out of the page
into its own component. Extracts the kind-to-plugin-key map that the picker,
the grid, and the favicon resolver each had a private copy of.
Asserts the behavior the redesign turns on, in a browser against a real instance: a provider browses as one card with its services hidden, opening it reveals them, back re-collapses, searching returns the services rather than the card, a protocol facet excludes other protocols, and a picked service lands on its add flow with the preset applied.
Keeps the picker's markup next to the page that owns it rather than in a component module of its own. Behavior is unchanged: the catalog logic stays in lib/preset-catalog.ts, and ConnectIntegrationDialog is file-local again.
Analytics already calls this surface the connect dialog (integration_connect_dialog_opened); the new event introduced a second noun for the same thing.
The dialog stayed mounted, so a URL detection the user walked away from still landed in its state. Abandoning one that then failed left the error banner waiting in the next open, under an empty search box; abandoning one that then succeeded navigated the app to that URL's add flow, whatever the user was doing by then. Both are in the new scenario, which fails on the old shape. ConnectIntegrationDialog is now a wrapper that renders its view only while open, so the query, facet, open provider and in-flight detection die with it instead of being hand-reset. Unmounting cannot stop handleDetect's continuation, which navigates, so a cleanup marks the withdrawn answer unwanted and it returns early.
One rule for "browses as a provider card": the picker collapsed any family with two or more presets while the integrations grid gated on MULTI_SERVICE_FAMILIES, so a plugin tagging presets with an uncurated family would get a card the rest of the app won't group behind. Both now ask curatedFamily(). No behavior change today — google and microsoft are the only families shipped. The protocol facets stand down inside a provider, where they counted the whole catalog over a list that isn't it and read "All" as selected over 21 of 39 cards. The add-manually links drop the pill shape they shared with those facets, so the same three protocol names stop meaning two things. Also: PresetIcon's unused alt and dead className defaults, a redundant empty-array check bestDetection already makes, and a protocol-filter sentinel no plugin key can collide with.
One PR, one changelog entry.
Making the links plain text to tell them apart from the protocol facets demoted a common way in to a footnote. They are three full buttons in a bordered footer now, each led by a plus and the verb — "Add MCP" cannot be mistaken for the "MCP 13" chip above, and it no longer reads as fine print.
The results box already ends in a border and the buttons draw their own, so the divider was a third line in forty pixels.
The results box was flex-1, so filtering to three results shrank the dialog and walked the facet chips out from under the cursor that had just clicked one. It has a fixed height now — min(36rem, 55vh), a window of eight or nine rows that a search cannot resize. The dialog's own 46rem cap goes with it, or it would have compressed that window back on a tall screen; 92vh still guards a short one.
The results grid draws its separators as gaps over a border-coloured background, so the last row had nothing under it and a short list ended in mid-air. A pixel of bottom padding exposes the same line. On a phone the protocol facets wrapped the last one onto its own row and the three add buttons wrapped onto a second, both pushing the dialog around. The facets scroll sideways now instead of wrapping, and below `sm` the add buttons collapse into one "Add manually" menu holding the same links. The scenario checks both at 390px: every facet chip shares a row, and the desktop buttons are gone in favour of the menu.
Measured at 390px: the add menu's items and the protocol chips were 32px tall, the search field 36, and every dialog's close button a bare 16x16 icon — that last one misses even the 24px WCAG 2.2 floor, let alone the 44px that WCAG 2.5.5, Apple, and Material all ask of a touch target. Phones now get 44px on the chips, the field, the manual-add trigger, and its menu items; wider viewports keep the tighter mouse-sized versions. The close button gets a 44px hit area at every width, grown with padding and pulled back by an equal negative margin so the glyph does not move. The scenario asserts no control in the dialog or its menu measures under 44px on a phone.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Currently the add integration modal is hard to discover the quick to setup integrations, its a small list making it hard to scroll, limiting discoverability and its unfilterable.

This pr makes it taller, two columns, grouping together integrations from the same provider, and filter down to api, mcp or graphql. making it easier to discover the available options.
