Skip to content

feat(ui,localizations,shared): add the organization Security page SSO overview#8813

Merged
iagodahlem merged 11 commits into
mainfrom
iago/orgs-1603-security-page-ui
Jun 15, 2026
Merged

feat(ui,localizations,shared): add the organization Security page SSO overview#8813
iagodahlem merged 11 commits into
mainfrom
iago/orgs-1603-security-page-ui

Conversation

@iagodahlem

@iagodahlem iagodahlem commented Jun 10, 2026

Copy link
Copy Markdown
Member

The Security page in <OrganizationProfile /> now renders an SSO overview instead of dropping straight into the configuration wizard:

  • Connection state at a glance — a status badge (Unconfigured / In Progress / Active / Inactive) driven by the connection entity's status, with per-state copy and actions (Start configuration / Continue configuration)
  • Enable SSO toggle — optimistic, gated on a successful test run
  • Inline configuration details — Provider (icon + name), Domain chips (multi-domain wraps), Sign on URL, Issuer, and Certificate, truncating with ellipsis + full-value tooltips for long SAML values
  • ⋯ menu — Edit (re-enters the wizard) and Delete (type-to-confirm using the organization name; lands back on the overview without a remount)

Start / Continue / Edit switch the page into the existing wizard via local view state — the temporary navigation until the wizard gets its back-to-Security header in the integration follow-up.

Under the hood: the page reads only the umbrella enterprise-connection hook and passes data down as props (the wizard's provider stays internal to the wizard), and ResetConnectionDialog is now context-free (hosts pass the delete action and portal root), so the page reuses it outside the wizard. Wizard behavior is unchanged.

States verified against design in light and dark. Known gaps deferred to the wizard-integration follow-up: Edit currently lands on the guard-derived step (the confirmation step for an active connection) rather than forcing step 1, and there's no in-wizard way back to the overview yet.

Summary by CodeRabbit

Summary by CodeRabbit

  • New Features

    • Added an SSO security overview to the Organization Profile with status badges (Unconfigured, In Progress, Active, Inactive).
    • Introduced an overview-to-wizard flow for configuring SSO, including provider/domain/sign-on details and contextual actions (edit, activate/deactivate, remove).
  • Localization & Customization

    • Expanded Security SSO localization (badge states, descriptions, remove confirmation, and action labels).
    • Added new appearance selectors to customize the Security SSO UI.
  • Tests

    • Added coverage for SSO states, navigation, menus, and remove/activate behaviors.

@vercel

vercel Bot commented Jun 10, 2026

Copy link
Copy Markdown

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

Project Deployment Actions Updated (UTC)
clerk-js-sandbox Ready Ready Preview, Comment Jun 15, 2026 6:23pm
swingset Ready Ready Preview, Comment Jun 15, 2026 6:23pm

Request Review

@changeset-bot

changeset-bot Bot commented Jun 10, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: cbe883d

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 21 packages
Name Type
@clerk/localizations Patch
@clerk/shared Patch
@clerk/ui Patch
@clerk/react Patch
@clerk/astro Patch
@clerk/backend Patch
@clerk/chrome-extension Patch
@clerk/clerk-js Patch
@clerk/expo-passkeys Patch
@clerk/expo Patch
@clerk/express Patch
@clerk/fastify Patch
@clerk/hono Patch
@clerk/msw Patch
@clerk/nextjs Patch
@clerk/nuxt Patch
@clerk/react-router Patch
@clerk/tanstack-react-start Patch
@clerk/testing Patch
@clerk/vue Patch
@clerk/swingset Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@coderabbitai

coderabbitai Bot commented Jun 10, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Repository UI (inherited)

Review profile: CHILL

Plan: Pro

Run ID: 18e3b857-d000-474f-84a5-6f9266a94be2

📥 Commits

Reviewing files that changed from the base of the PR and between d0b0186 and cbe883d.

📒 Files selected for processing (2)
  • packages/localizations/src/en-US.ts
  • packages/ui/src/components/OrganizationProfile/__tests__/OrganizationSecurityPage.test.tsx
✅ Files skipped from review due to trivial changes (1)
  • packages/localizations/src/en-US.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/ui/src/components/OrganizationProfile/tests/OrganizationSecurityPage.test.tsx

📝 Walkthrough

Walkthrough

Adds an SSO overview page to the Organization Profile Security section. The new SecuritySsoSection component renders status badges, configuration details, and an actions menu (edit, activate/deactivate with optimistic UI, remove). OrganizationSecurityPage gains view-switching between overview and wizard. ResetConnectionDialog is refactored to accept onDelete and contentRef as props, decoupling it from context. New localization keys, appearance selectors, and comprehensive tests are included.

Changes

SSO Overview Page for Organization Profile Security

Layer / File(s) Summary
Shared localization, appearance, and element ID contracts
.changeset/orange-pandas-shake.md, packages/shared/src/types/localization.ts, packages/localizations/src/en-US.ts, packages/shared/src/types/elementIds.ts, packages/ui/src/internal/appearance.ts, packages/ui/src/customizables/elementDescriptors.ts
Adds securityPage.ssoSection.* localization keys to LocalizationResource and enUS including badge states, description lines (with/without role), provider/domain/sign-on/issuer/certificate labels, and menu action labels; extends ElementsConfig and APPEARANCE_KEYS with organizationProfileSecuritySso* selectors; reformats ProfileSectionId/ProfilePageId unions; records patch changeset.
Section badge prop for SectionHeader
packages/ui/src/elements/Section.tsx
ProfileSectionRoot gains an optional badge prop forwarded into SectionHeader, which now renders children after the title text to support inline SSO status badge display.
ResetConnectionDialog refactored to accept onDelete and contentRef
packages/ui/src/components/ConfigureSSO/ResetConnectionDialog.tsx, packages/ui/src/components/ConfigureSSO/__tests__/ResetConnectionDialog.test.tsx
ResetConnectionDialogProps adds onDelete (async callback) and contentRef (portal root) plus optional title, subtitle, confirmButtonLabel; dialog no longer reads enterpriseConnection or mutations from useConfigureSSO context; onSubmit gates on canSubmit, awaits onDelete(), then closes on success; tests updated to pass new props and verify prop-driven labels.
ConfigureSSO Step and ConfirmationStep wire refactored ResetConnectionDialog
packages/ui/src/components/ConfigureSSO/elements/Step.tsx, packages/ui/src/components/ConfigureSSO/steps/ConfirmationStep.tsx
FooterReset and ResetConnectionSection extract enterpriseConnection, mutations, and contentRef from useConfigureSSO context and wire them to ResetConnectionDialog as onDelete callback and contentRef prop.
SecuritySsoSection overview component
packages/ui/src/components/OrganizationProfile/SecuritySsoSection.tsx
New SecuritySsoSection renders three status-driven states: unconfigured and in-progress show description plus a configure button; active/inactive render a configured card with provider icon, enrolled domain chips, and SAML details. Includes a three-dots menu for edit, activate/deactivate (with optimistic badge UI and rollback), and remove (via ResetConnectionDialog). SsoDescription localizes enrollment text and derives effective role name via useEnrollmentRoleName (environment defaults, readable roles, humanized fallback). Helper components: DetailRow, ValueChip, LinkChip, ProviderIcon.
OrganizationSecurityPage view-switching orchestration
packages/ui/src/components/OrganizationProfile/OrganizationSecurityPage.tsx
OrganizationSecurityPageContent gains local view state ('overview' | 'wizard'), rendering SecuritySsoSection in overview or ConfigureSSOWizard in wizard mode with shared hook-provided connection data and view-switching handlers.
OrganizationSecurityPage and ResetConnectionDialog tests
packages/ui/src/components/OrganizationProfile/__tests__/OrganizationSecurityPage.test.tsx
Comprehensive Vitest suite covering unconfigured/in-progress/active/inactive overview states, SAML value truncation with title attributes, view switching, actions menu item sets by status, remove confirmation dialog with type-to-confirm, optimistic activate/deactivate with badge flipping and error rollback, and enrollment role display variants (readable names, humanized fallback, missing default role).

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant OrganizationSecurityPage
  participant SecuritySsoSection
  participant ConfigureSSOWizard
  participant EnterpriseConnectionMutations

  User->>OrganizationSecurityPage: navigates to Security page
  OrganizationSecurityPage->>SecuritySsoSection: renders overview (view='overview')
  SecuritySsoSection->>User: shows status badge + detail rows + actions menu

  alt Start/Continue/Edit clicked
    User->>SecuritySsoSection: clicks configure button or Edit
    SecuritySsoSection->>OrganizationSecurityPage: setView('wizard')
    OrganizationSecurityPage->>ConfigureSSOWizard: renders wizard
  else Activate/Deactivate clicked
    User->>SecuritySsoSection: clicks Activate or Deactivate
    SecuritySsoSection->>SecuritySsoSection: sets optimistic status override
    SecuritySsoSection->>EnterpriseConnectionMutations: updateConnection(active)
    EnterpriseConnectionMutations-->>SecuritySsoSection: settled (success or error)
    SecuritySsoSection->>SecuritySsoSection: clears optimistic override (or rollback)
  else Remove clicked
    User->>SecuritySsoSection: clicks Remove
    SecuritySsoSection->>SecuritySsoSection: opens ResetConnectionDialog
    User->>SecuritySsoSection: types confirmation
    SecuritySsoSection->>EnterpriseConnectionMutations: deleteConnection(id)
    EnterpriseConnectionMutations-->>SecuritySsoSection: resolved
    SecuritySsoSection->>OrganizationSecurityPage: connection removed
  end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

  • clerk/javascript#8796: Renamed/routed the self-serve SSO page to OrganizationSecurityPage, which this PR builds directly on top of to add the overview UI.
  • clerk/javascript#8799: Modified the ConfigureSSO wizard/view-level orchestration that OrganizationSecurityPage now wraps with view-switching logic.
  • clerk/javascript#8715: Changed the ConfigureSSO reset/delete flow in ResetConnectionDialog.tsx, which this PR refactors further to prop-based injection.

Suggested labels

testing

Suggested reviewers

  • LauraBeatris

Poem

🐰 Hop, hop, hooray for the overview page!
The SSO badge gleams on security's stage,
Active or dormant, configured or bare,
A menu of actions floats right in the air.
Edit, Deactivate, Remove with a click—
The wizard awaits if you need a new trick! ✨

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title directly and clearly describes the main change: adding an SSO overview section to the Organization Security page.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch

Comment @coderabbitai help to get the list of available commands and usage tips.

@iagodahlem iagodahlem force-pushed the iago/orgs-1603-configure-sso-data-ownership branch from 168e840 to 9a40534 Compare June 11, 2026 19:47
@iagodahlem iagodahlem force-pushed the iago/orgs-1603-security-page-ui branch from 8ab736d to 4f61358 Compare June 11, 2026 19:47
Base automatically changed from iago/orgs-1603-configure-sso-data-ownership to main June 11, 2026 20:03
@iagodahlem iagodahlem force-pushed the iago/orgs-1603-security-page-ui branch from 4f61358 to 87bd9f2 Compare June 11, 2026 20:04
@pkg-pr-new

pkg-pr-new Bot commented Jun 11, 2026

Copy link
Copy Markdown

Open in StackBlitz

@clerk/astro

npm i https://pkg.pr.new/@clerk/astro@8813

@clerk/backend

npm i https://pkg.pr.new/@clerk/backend@8813

@clerk/chrome-extension

npm i https://pkg.pr.new/@clerk/chrome-extension@8813

@clerk/clerk-js

npm i https://pkg.pr.new/@clerk/clerk-js@8813

@clerk/expo

npm i https://pkg.pr.new/@clerk/expo@8813

@clerk/expo-passkeys

npm i https://pkg.pr.new/@clerk/expo-passkeys@8813

@clerk/express

npm i https://pkg.pr.new/@clerk/express@8813

@clerk/fastify

npm i https://pkg.pr.new/@clerk/fastify@8813

@clerk/hono

npm i https://pkg.pr.new/@clerk/hono@8813

@clerk/localizations

npm i https://pkg.pr.new/@clerk/localizations@8813

@clerk/nextjs

npm i https://pkg.pr.new/@clerk/nextjs@8813

@clerk/nuxt

npm i https://pkg.pr.new/@clerk/nuxt@8813

@clerk/react

npm i https://pkg.pr.new/@clerk/react@8813

@clerk/react-router

npm i https://pkg.pr.new/@clerk/react-router@8813

@clerk/shared

npm i https://pkg.pr.new/@clerk/shared@8813

@clerk/tanstack-react-start

npm i https://pkg.pr.new/@clerk/tanstack-react-start@8813

@clerk/testing

npm i https://pkg.pr.new/@clerk/testing@8813

@clerk/ui

npm i https://pkg.pr.new/@clerk/ui@8813

@clerk/upgrade

npm i https://pkg.pr.new/@clerk/upgrade@8813

@clerk/vue

npm i https://pkg.pr.new/@clerk/vue@8813

commit: cbe883d

@github-actions

github-actions Bot commented Jun 15, 2026

Copy link
Copy Markdown
Contributor

API Changes Report

Generated by Break Check on 2026-06-15T18:26:09.148Z

Summary

Metric Count
Packages analyzed 19
Packages with changes 2
🔴 Breaking changes 0
🟡 Non-breaking changes 4
🟢 Additions 0

🤖 This report was reviewed by claude-sonnet-4-6.

Note
Break Check could not snapshot 3 subpaths; the diff below excludes them.

  • @clerk/astro ./env: ambient declaration file (no top-level import or export): API Extractor can only analyze module entry points, so this global-augmentation surface cannot be snapshotted; add "@clerk/astro#./env" to ignoreSubpaths to acknowledge it (API Extractor: Unable to determine module for: /home/runner/_work/javascript/javascript/packages/astro/env.d.ts)
  • @clerk/shared ./cookie: the shipped declarations reference the type name "Cookies", which cannot be resolved from the entry point; the published types are likely broken for consumers (often a dropped import or a types package that is only a devDependency); fix the published types, or add "@clerk/shared#./cookie" to ignoreSubpaths as a stopgap (API Extractor: Unable to follow symbol for "Cookies")
  • @clerk/testing ./cypress: the shipped declarations reference the type name "Cypress", which cannot be resolved from the entry point; the published types are likely broken for consumers (often a dropped import or a types package that is only a devDependency); fix the published types, or add "@clerk/testing#./cypress" to ignoreSubpaths as a stopgap (API Extractor: Symbol not found for identifier: Cypress)

@clerk/shared

Current version: 4.17.1
Recommended bump: MINOR → 4.18.0

Subpath ./types

🟡 Non-breaking Changes (3)

Modified: __internal_LocalizationResource
// ... 1037 unchanged lines elided ...
        messageLine2: LocalizationValue;
        successMessage: LocalizationValue;
      };
+     securityPage: {
+       title: LocalizationValue;
+       removeDialog: {
+         title: LocalizationValue;
+         subtitle: LocalizationValue;
+         confirmButton: LocalizationValue;
+       };
+       ssoSection: {
+         title: LocalizationValue;
+         badge__unconfigured: LocalizationValue;
+         badge__inProgress: LocalizationValue;
+         badge__active: LocalizationValue;
+         badge__inactive: LocalizationValue;
+         descriptionLine1: LocalizationValue;
+         descriptionLine2: LocalizationValue<'role'>;
+         descriptionLine2__noRole: LocalizationValue;
+         primaryButton__startConfiguration: LocalizationValue;
+         primaryButton__continueConfiguration: LocalizationValue;
+         providerLabel: LocalizationValue;
+         domainLabel: LocalizationValue;
+         signOnUrlLabel: LocalizationValue;
+         issuerLabel: LocalizationValue;
+         certificateLabel: LocalizationValue;
+         menuAction__edit: LocalizationValue;
+         menuAction__activate: LocalizationValue;
+         menuAction__deactivate: LocalizationValue;
+         menuAction__remove: LocalizationValue;
+       };
+     };
      membersPage: {
        detailsTitle__emptyRow: LocalizationValue;
        action__invite: LocalizationValue;
// ... 881 unchanged lines elided ...

Static analyzer: Breaking change in type alias __internal_LocalizationResource: Type changed: {locale:string;maintenanceMode:import("@clerk/shared").LocalizationValue;roles:{[r:string]:import("@clerk/shared").Loca…{locale:string;maintenanceMode:import("@clerk/shared").LocalizationValue;roles:{[r:string]:import("@clerk/shared").Loca…

🤖 AI review (reclassified as non-breaking) (70%): The before and after snippets show the same structure at the visible boundaries; the difference is in elided lines (1844 vs 1873), indicating new fields were added. __internal_LocalizationResource is used as the basis for LocalizationResource which extends DeepPartial<DeepLocalizationWithoutObjects<__internal_LocalizationResource>>, meaning consumers only read/construct LocalizationResource (an output/partial type), so adding new fields to the internal source type does not break existing consumers.

Modified: ProfilePageId
- type ProfilePageId = 'account' | 'security' | 'organizationGeneral' | 'organizationMembers' | 'billing';
+ type ProfilePageId = 'account' | 'security' | 'organizationGeneral' | 'organizationMembers' | 'organizationSecurity' | 'billing';

Static analyzer: Breaking change in type alias ProfilePageId: Type changed: 'account'|'billing'|'organizationGeneral'|'organizationMembers'|'security''account'|'billing'|'organizationGeneral'|'organizationMembers'|'organizationSecurity'|'security'

🤖 AI review (reclassified as non-breaking) (85%): A new variant 'organizationSecurity' was added to the ProfilePageId union; existing code that exhaustively switches or assigns this union may not handle the new variant, but adding a union member to an output/discriminated type is an additive change. However, if consumers use this as an input type (e.g., passing a value of this type), widening the union is non-breaking for inputs. The addition of a new member does not invalidate existing members.

Modified: ProfileSectionId
- type ProfileSectionId = 'profile' | 'username' | 'emailAddresses' | 'phoneNumbers' | 'connectedAccounts' | 'enterpriseAccounts' | 'web3Wallets' | 'password' | 'passkeys' | 'mfa' | 'danger' | 'activeDevices' | 'organizationProfile' | 'organizationDanger' | 'organizationDomains' | 'manageVerifiedDomains' | 'subscriptionsList' | 'paymentMethods' | 'ssoStatus' | 'enableSso' | 'ssoDomain' | 'ssoConfiguration' | 'configureAgain' | 'resetSso' | 'testSsoUrl' | 'testResults';
+ type ProfileSectionId = 'profile' | 'username' | 'emailAddresses' | 'phoneNumbers' | 'connectedAccounts' | 'enterpriseAccounts' | 'web3Wallets' | 'password' | 'passkeys' | 'mfa' | 'danger' | 'activeDevices' | 'organizationProfile' | 'organizationDanger' | 'organizationDomains' | 'manageVerifiedDomains' | 'subscriptionsList' | 'paymentMethods' | 'sso' | 'ssoStatus' | 'enableSso' | 'ssoDomain' | 'ssoConfiguration' | 'configureAgain' | 'resetSso' | 'testSsoUrl' | 'testResults';

Static analyzer: Breaking change in type alias ProfileSectionId: Type changed: 'activeDevices'|'configureAgain'|'connectedAccounts'|'danger'|'emailAddresses'|'enableSso'|'enterpriseAccounts'|'manage…'activeDevices'|'configureAgain'|'connectedAccounts'|'danger'|'emailAddresses'|'enableSso'|'enterpriseAccounts'|'manage…

🤖 AI review (reclassified as non-breaking) (80%): A new variant 'sso' was added to the ProfileSectionId union; existing members are all preserved, so no previously valid value is removed. Adding a new union member to an output type used in MenuId is an additive change and does not break existing consumers who handle only previously existing members.


@clerk/ui

Current version: 1.16.1
Recommended bump: MINOR → 1.17.0

Subpath ./internal

🟡 Non-breaking Changes (1)

Modified: ElementsConfig
// ... 182 unchanged lines elided ...
    organizationSwitcherPopoverFooter: WithOptions;
    organizationProfileMembersSearchInputIcon: WithOptions;
    organizationProfileMembersSearchInput: WithOptions;
+   organizationProfileSecuritySsoBadge: WithOptions<string>;
+   organizationProfileSecuritySsoDescription: WithOptions;
+   organizationProfileSecuritySsoConfigureButton: WithOptions<string>;
+   organizationProfileSecuritySsoDetailRows: WithOptions;
+   organizationProfileSecuritySsoDetailRow: WithOptions<string>;
+   organizationProfileSecuritySsoDetailRowLabel: WithOptions<string>;
+   organizationProfileSecuritySsoDetailRowChip: WithOptions<string>;
+   organizationProfileSecuritySsoDetailRowLink: WithOptions<string>;
+   organizationProfileSecuritySsoProviderIcon: WithOptions;
    organizationListPreviewItems: WithOptions;
    organizationListPreviewItem: WithOptions;
    organizationListPreviewButton: WithOptions;
// ... 343 unchanged lines elided ...

Static analyzer: Breaking change in type alias ElementsConfig: Type changed: {button:import("@clerk/ui").~WithOptions<string>;input:import("@clerk/ui").~WithOptions;checkbox:import("@clerk/ui").~W…{button:import("@clerk/ui").~WithOptions<string>;input:import("@clerk/ui").~WithOptions;checkbox:import("@clerk/ui").~W…

🤖 AI review (reclassified as non-breaking) (85%): The change adds new properties to ElementsConfig (9 more lines elided in the after-snippet), and ElementsConfig is used only as a mapped-type source for the output type Elements — consumers only read Elements values, they do not construct ElementsConfig objects — so adding new keys is non-breaking.


Report generated by Break Check

Last ran on cbe883d.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (2)
packages/ui/src/components/OrganizationProfile/__tests__/OrganizationSecurityPage.test.tsx (2)

28-42: 🏗️ Heavy lift

Reduce as any usage in fixture builders to preserve type-safety in tests.

configuredConnection (and several follow-up mock payloads) rely on as any, which can hide contract drift between tests and production types. Prefer typed fixtures (satisfies, explicit interfaces, or helper factory return types) so API-shape changes fail at compile time.

As per coding guidelines: “Avoid any type… No any types without justification in code review.”

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@packages/ui/src/components/OrganizationProfile/__tests__/OrganizationSecurityPage.test.tsx`
around lines 28 - 42, The configuredConnection fixture builder function uses an
`as any` cast which bypasses TypeScript's type checking and can hide contract
drift between tests and production code. Remove the `as any` cast and instead
use proper TypeScript typing by either using the `satisfies` keyword with the
correct type, or explicitly defining the return type of the configuredConnection
function to match the actual connection type used in production. This will
ensure API-shape changes cause compile-time failures rather than being hidden by
the loose typing.

Source: Coding guidelines


181-185: ⚡ Quick win

Prefer behavior assertions over CSS implementation details in truncation tests.

At Line 181 and Line 185, checking exact overflow/textOverflow/whiteSpace styles makes the test brittle to presentational refactors. Validate user-visible behavior (e.g., full value is accessible via title, link target remains correct) without asserting internal style mechanics.

As per coding guidelines: “Test component behavior, not implementation details.”

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@packages/ui/src/components/OrganizationProfile/__tests__/OrganizationSecurityPage.test.tsx`
around lines 181 - 185, Remove the brittle CSS style assertions from the
truncation tests in OrganizationSecurityPage.test.tsx. For both the ssoLink
element (around line 181) and the certificate element (around line 185), delete
the toHaveStyle calls that check for overflow, textOverflow, and whiteSpace
properties. Keep the behavior-focused assertions like toHaveAttribute that
verify the full values are accessible via the title attribute, which is what
actually matters to users. This refactoring shifts the test from asserting
presentation implementation details to validating user-visible behavior.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In
`@packages/ui/src/components/OrganizationProfile/__tests__/OrganizationSecurityPage.test.tsx`:
- Around line 28-42: The configuredConnection fixture builder function uses an
`as any` cast which bypasses TypeScript's type checking and can hide contract
drift between tests and production code. Remove the `as any` cast and instead
use proper TypeScript typing by either using the `satisfies` keyword with the
correct type, or explicitly defining the return type of the configuredConnection
function to match the actual connection type used in production. This will
ensure API-shape changes cause compile-time failures rather than being hidden by
the loose typing.
- Around line 181-185: Remove the brittle CSS style assertions from the
truncation tests in OrganizationSecurityPage.test.tsx. For both the ssoLink
element (around line 181) and the certificate element (around line 185), delete
the toHaveStyle calls that check for overflow, textOverflow, and whiteSpace
properties. Keep the behavior-focused assertions like toHaveAttribute that
verify the full values are accessible via the title attribute, which is what
actually matters to users. This refactoring shifts the test from asserting
presentation implementation details to validating user-visible behavior.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Repository UI (inherited)

Review profile: CHILL

Plan: Pro

Run ID: 5427296a-61bb-4438-98f4-1fa565162192

📥 Commits

Reviewing files that changed from the base of the PR and between 4cd455e and e72710f.

📒 Files selected for processing (14)
  • .changeset/orange-pandas-shake.md
  • packages/localizations/src/en-US.ts
  • packages/shared/src/types/elementIds.ts
  • packages/shared/src/types/localization.ts
  • packages/ui/src/components/ConfigureSSO/ResetConnectionDialog.tsx
  • packages/ui/src/components/ConfigureSSO/__tests__/ResetConnectionDialog.test.tsx
  • packages/ui/src/components/ConfigureSSO/elements/Step.tsx
  • packages/ui/src/components/ConfigureSSO/steps/ConfirmationStep.tsx
  • packages/ui/src/components/OrganizationProfile/OrganizationSecurityPage.tsx
  • packages/ui/src/components/OrganizationProfile/SecuritySsoSection.tsx
  • packages/ui/src/components/OrganizationProfile/__tests__/OrganizationSecurityPage.test.tsx
  • packages/ui/src/customizables/elementDescriptors.ts
  • packages/ui/src/elements/Section.tsx
  • packages/ui/src/internal/appearance.ts

@iagodahlem iagodahlem requested a review from LauraBeatris June 15, 2026 14:08
…polish

Remove the optimistic-active state mirror so the badge and menu read straight from the revalidated connection, and apply the detail-card spacing, alignment, and caption adjustments.
Comment on lines +232 to +234
// The footer self-hides without a connection (`hasConnection` above), so the resource is set.
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
onDelete={() => mutations.deleteConnection(enterpriseConnection!.id)}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could also do !enterpriseConnection above so avoid ! here, what would be the difference with hasConnection?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No difference, good call! 👍

// footer (including the nested SAML configure footers) without binding to
// a nested wizard.
await mutations.deleteConnection(enterpriseConnection.id);
// A pure delete, no navigation — the wizard self-corrects once the active step's entry guard breaks.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// A pure delete, no navigation — the wizard self-corrects once the active step's entry guard breaks.

sx={t => ({ gap: t.space.$8 })}
>
<Col
elementDescriptor={descriptors.profilePage}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need this nested Col here for layout purposes? Or it is used to apply a different descriptor?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, it mirrors the OrganizationGeneralPage (Col descriptors.page → Col descriptors.profilePage); the inner Col carries the profilePage descriptor, so I kept it for consistency.

Comment on lines +68 to +69
connection={organizationEnterpriseConnection}
enterpriseConnection={enterpriseConnection}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need both organizationEnterpriseConnection and enterpriseConnection? Is it possible to access enterpriseConnection within organizationEnterpriseConnection?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, that's a bit confusing. Today, the entity drives the status/menu decisions, and the raw connection supplies the display fields it doesn't carry (domains, samlConnection.*, id). Rather than fold them hastily, I've opened a follow-up to consolidate to a single prop in its own PR so we get the shape right.

import { ResetConnectionDialog } from '../ConfigureSSO/ResetConnectionDialog';
import type { ProviderType } from '../ConfigureSSO/types';

/** Props-driven: the Security page owns the data — no wizard context below the page. */

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/** Props-driven: the Security page owns the data — no wizard context below the page. */

},
};

/** Keep in sync with the select-provider step's MONOCHROMATIC_PROVIDER_ICONS. */

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/** Keep in sync with the select-provider step's MONOCHROMATIC_PROVIDER_ICONS. */

Perhaps a shared constant for the steps? Also think it's not an issue to keep duplicated

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 Left it duplicated for now

@LauraBeatris

Copy link
Copy Markdown
Member
CleanShot 2026-06-15 at 14 55 51

Is this horizontal padding expected or do we expect the divider to take the whole space?

@LauraBeatris

Copy link
Copy Markdown
Member

"Let members sign in through your identity provider using their domain email" -> "domain email" reads weirdly... I think it should be email domain instead but waiting on confirmation

Drop three reviewer-flagged comments and remove the FooterReset non-null assertion by narrowing on the raw enterpriseConnection resource in the hide guard.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants