[Portal] Migrate Advanced settings screens to Radix UI#5771
Open
fungc-io wants to merge 23 commits into
Open
Conversation
Add password type and plain suffix support on TextField, optional labelSize on FormField, and match disabled SecondaryButton styling to the design system. Co-authored-by: Cursor <cursoragent@cursor.com>
Introduce a floating save bar aligned to content width, with discard confirmation and Storybook coverage. Co-authored-by: Cursor <cursoragent@cursor.com>
Replace the enable toggle with provider cards, adopt v2 form controls and SaveFunctionBar, update typography and spacing to match design, and swap provider logos to SVG assets. Co-authored-by: Cursor <cursoragent@cursor.com>
Use v2 components for Admin API Configuration screen and make the keys table horizontally scrollable on narrow viewports. Co-authored-by: Cursor <cursoragent@cursor.com>
Use ConfirmationDialog for SaveFunctionBar, FormContainer reset, and navigation blocker flows. Raise dialog overlay z-index so Monaco editor UI does not paint above the modal mask. Co-authored-by: Cursor <cursoragent@cursor.com>
Document default, checked, with-text, and disabled Toggle variants. Co-authored-by: Cursor <cursoragent@cursor.com>
Refactor Account Deletion, Account Anonymization, Cookie Lifetime, Endpoint Direct Access, SMTP, SMS Provider, Admin API, Edit Config, and SAML Certificate to v2 layout patterns with SaveFunctionBar. Align content width to Admin API grid span 9 and add page descriptions. Co-authored-by: Cursor <cursoragent@cursor.com>
Use inline path elements instead of a base64 PNG for sharper rendering. Co-authored-by: Cursor <cursoragent@cursor.com>
Restore the required-field indicator and the label/input association that the
Radix/v2 migration dropped from the Advanced-settings screens.
- FormField: add `required` (renders a red asterisk) and `htmlFor` (renders the
label as a <label htmlFor> so clicking focuses the control and screen readers
announce the pairing).
- TextField: generate an id, forward it to the label (htmlFor) and the input
(id), and pass `required` through to the input.
- Re-mark the SMTP and SMS fields that carried required={true} before the
migration; for the Twilio sender/credential radio groups the marker goes on
the group FormField label.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The send-test-email dialog was left as a Fluent Dialog while its Send/Cancel buttons were migrated to the v2 (Radix) PrimaryButton/SecondaryButton. Fluent's Dialog portals to a Layer on document.body, outside the Radix <Theme> provider, so the Radix buttons rendered without their theme tokens and were invisible. Migrate the dialog to a Radix Dialog (matching the ConfirmationDialog pattern) so its content renders inside the Theme context. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The copy-to-clipboard icon button was duplicated verbatim in AdminAPIConfigurationScreen and SMSProviderConfigurationScreen, and neither copy cleared its 2s "copied" reset timer on unmount (it fired setState on an unmounted component when a table row was removed or the screen was left). Extract a single components/v2/CopyIconButton that clears the timer in an effect cleanup, and use it in both screens. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The key-row "Download" action used Pencil1Icon (an edit icon); switch it to DownloadIcon. When only one key remains, Delete is disabled with no explanation — restore the "At least 1 key per project" hint (reusing the AdminAPIConfigurationScreen.keys.delete.tooltip string the migration had orphaned) as a DropdownMenu.Label shown below the disabled item. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The alignment hook only measured the anchor on a one-shot layout effect keyed by the ref object, used getBoundingClientRect + setState on every scroll event with no throttle, and located the scroll container with a fragile overflowY walk that missed window-level scrolling. - rAF-coalesce measurements and skip setState when left/width are unchanged, so scrolling no longer re-renders the bar every frame. - Listen for scroll in the capture phase on window, which catches any ancestor scroll container (nested or the window/document) without locating it. - Retry measurement until a late-mounting anchor appears, and (re)observe the current anchor element, instead of giving up when it is null. - Hoist the discard dialog's onOpenChange into a stable useCallback. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The hint shown when only one key remains is unnecessary; keep the download icon fix and remove the DropdownMenu.Label hint (and its CSS). The AdminAPIConfigurationScreen.keys.delete.tooltip string is unused again and is removed with the other dead i18n keys. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Drop three portal translation keys no longer referenced after the migration: - AdminAPIConfigurationScreen.keys.delete.tooltip - EndpointDirectAccessScreen.section1.option.ShowLoginAndRedirectToSettings.label--disabled - EndpointDirectAccessScreen.section1.option.ShowLoginAndRedirectToCustomURL.label--disabled Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The Radix migration left the migrated screens failing `make -C portal lint`. Make them lint-clean: - Replace forbidden raw <h1> page titles with <Text as="p" size="5" weight="bold"> to match the other migrated screens (react/forbid-elements). - Set explicit values on boolean JSX attributes: aria-hidden, suffixPlain, hideFooterComponent (react/jsx-boolean-value). - Capture e.target.value before the nested setState updater in the Cookie Lifetime and Endpoint Direct Access change handlers (local/no-unsafe-react-event-usage). - Remove two now-unnecessary react/no-unstable-nested-components disable directives in Endpoint Direct Access. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The migration had stored sendgrid_logo.svg as a base64 PNG wrapped in an SVG <image> element (no vector benefit, still rasterized). Replace it with a true vector SendGrid mark, consistent with the other provider logos. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The provider selection cards passed a fixed numberOfColumns (4 for SMS, 3 for SMTP), producing a repeat(N, minmax(160px, 1fr)) grid that cannot wrap: once the content column is narrower than N*160px it overflows and crops the last card. - Drop numberOfColumns at both call sites so the grid uses the responsive auto-fit default, which wraps to a new row instead of overflowing (and still shows all cards in one row when wide, capped by the item count). - Vertically center the icon + label of title-only cards so a wrapped label stays aligned with the equal-height sibling cards; cards with a subtitle (Project Wizard) keep top alignment. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
ConfirmationDialog rendered the confirm (primary) button on the left and cancel on the right, while SaveFunctionBar puts the primary action on the right. Swap the dialog's order to cancel-left / confirm-right so all dialogs and the save bar share one convention. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The save bar previously mounted and unmounted instantly. Keep it mounted across the exit and play a slide + fade via CSS keyframes: saveFunctionBarIn on appear, saveFunctionBarOut on disappear (then unmount). Respects prefers-reduced-motion. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The save-bar screens rendered a zero-height contentWidthAnchor div as the first grid child purely to measure the content-column width. In ScreenContent's grid (row-gap: 20px) that empty leading row pushed the page title ~20px lower than on Admin API, which has no save bar. Attach the SaveFunctionBar measurement ref to the existing pageHeader (which already spans the content column) and drop the dedicated anchor div and its CSS. The title now sits flush at the top on every Advanced page, consistent with Admin API, and the save bar still aligns to the content column. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…reens The label-left / content-right settings card was duplicated inline across the migrated Advanced screens, with an inconsistent label width (Admin API 140px vs others 200px) and only Admin API stacking responsively on narrow viewports. - Add components/v2/SettingsSectionCard: a bordered card with a 200px label column that stacks vertically on tablet, plus a Storybook story. - Migrate Account Deletion, Account Anonymization, Cookie Lifetime, Endpoint Direct Access, SAML Certificate, SMTP and SMS onto it. - Widen Admin API's section label to 200px to match, and drop SAML's now-dead sectionHeading CSS. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Make the migrated Advanced screens pass `make -C portal` CI checks: - eslint: set explicit values on bare boolean JSX attributes (aria-hidden, startClean) in SaveFunctionBar stories. - stylelint: silence no-unsupported-browser-features for the scrollbar-hiding rules (Admin API + SAML key tables), and replace the deprecated word-break: break-word with overflow-wrap: break-word in v2 Callout. - prettier: format the screens/components left unformatted by the migration (project pins prettier 2.x). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
6 tasks
Member
Author
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.



Summary
Migrate the Advanced settings screens to the Radix/v2 component system. This is the non–Hook-page portion of #5761 (the Hooks-page migration is excluded), plus a round of review-driven fixes on top.
Migration (v2 component adoption)
SaveFunctionBar, and Radix dialogs.SaveFunctionBar,ConfirmationDialog, extendedTextField/FormField/SecondaryButton, Toggle stories.Review fixes layered on top
FormField/TextField).CopyIconButton: extract one shared v2 component with proper unmount cleanup (was duplicated and leaked a timer).SaveFunctionBar: robust content-column alignment (handles late-mounting anchor, window/nested scroll), rAF-throttled, and an appear/disappear animation.v2/SettingsSectionCard(label + content, responsive stacking) and adopt it across the Advanced screens; align page-title spacing.Test plan
cd portal && npm run typechecknpm run eslint/npm run stylelint/npm run prettiernpm run browserslist-coverage-lintnpm test(jest)🤖 Generated with Claude Code