From 400afeba2d59deeacd08f5e86ad0b3340dc568e1 Mon Sep 17 00:00:00 2001 From: Jim Kalafut Date: Tue, 22 Sep 2026 14:44:20 -0700 Subject: [PATCH 1/3] fix(ui): update self-serve sso & directory sync to latest designs - replace the "Start configuration" button on the Security tab with a "Configure" arrow button - use a three-dot row menus - neutral badge colors and updated placement --- .changeset/security-page-redesign.md | 9 + packages/localizations/src/ar-SA.ts | 4 +- packages/localizations/src/be-BY.ts | 4 +- packages/localizations/src/bg-BG.ts | 4 +- packages/localizations/src/bn-IN.ts | 4 +- packages/localizations/src/ca-ES.ts | 4 +- packages/localizations/src/cs-CZ.ts | 4 +- packages/localizations/src/da-DK.ts | 4 +- packages/localizations/src/de-DE.ts | 4 +- packages/localizations/src/el-GR.ts | 4 +- packages/localizations/src/en-GB.ts | 4 +- packages/localizations/src/en-US.ts | 9 +- packages/localizations/src/es-CR.ts | 4 +- packages/localizations/src/es-ES.ts | 4 +- packages/localizations/src/es-MX.ts | 4 +- packages/localizations/src/es-UY.ts | 4 +- packages/localizations/src/fa-IR.ts | 4 +- packages/localizations/src/fi-FI.ts | 4 +- packages/localizations/src/fr-FR.ts | 4 +- packages/localizations/src/he-IL.ts | 4 +- packages/localizations/src/hi-IN.ts | 4 +- packages/localizations/src/hr-HR.ts | 4 +- packages/localizations/src/hu-HU.ts | 4 +- packages/localizations/src/id-ID.ts | 4 +- packages/localizations/src/is-IS.ts | 4 +- packages/localizations/src/it-IT.ts | 4 +- packages/localizations/src/ja-JP.ts | 4 +- packages/localizations/src/kk-KZ.ts | 4 +- packages/localizations/src/ko-KR.ts | 4 +- packages/localizations/src/mn-MN.ts | 4 +- packages/localizations/src/ms-MY.ts | 4 +- packages/localizations/src/nb-NO.ts | 4 +- packages/localizations/src/nl-BE.ts | 4 +- packages/localizations/src/nl-NL.ts | 4 +- packages/localizations/src/pl-PL.ts | 4 +- packages/localizations/src/pt-BR.ts | 4 +- packages/localizations/src/pt-PT.ts | 4 +- packages/localizations/src/ro-RO.ts | 4 +- packages/localizations/src/ru-RU.ts | 4 +- packages/localizations/src/sk-SK.ts | 4 +- packages/localizations/src/sr-RS.ts | 4 +- packages/localizations/src/sv-SE.ts | 4 +- packages/localizations/src/ta-IN.ts | 4 +- packages/localizations/src/te-IN.ts | 4 +- packages/localizations/src/th-TH.ts | 4 +- packages/localizations/src/tr-TR.ts | 4 +- packages/localizations/src/uk-UA.ts | 4 +- packages/localizations/src/vi-VN.ts | 4 +- packages/localizations/src/zh-CN.ts | 4 +- packages/localizations/src/zh-TW.ts | 4 +- packages/shared/src/types/localization.ts | 7 +- .../SecurityDirectorySyncSection.tsx | 70 ++-- .../ConfigureSSO/domain/providers.ts | 5 + .../ConfigureSSO/steps/SelectProviderStep.tsx | 4 +- .../EnterpriseConnectionIcon.tsx | 40 ++ .../DangerZoneSection.tsx | 125 ------- .../EnterpriseConnectionPage/index.tsx | 172 +++------ .../OrganizationSecurityPage.tsx | 35 +- .../SecuritySsoSection.tsx | 343 ++++++++++-------- .../EnterpriseConnectionPage.test.tsx | 100 +---- .../__tests__/OrganizationProfile.test.tsx | 4 +- .../OrganizationSecurityPage.test.tsx | 237 +++++++----- .../__tests__/SSOBypassAllowlist.test.tsx | 23 +- .../enterpriseConnectionStatusBadges.ts | 8 +- 64 files changed, 626 insertions(+), 757 deletions(-) create mode 100644 .changeset/security-page-redesign.md create mode 100644 packages/ui/src/components/OrganizationProfile/EnterpriseConnectionIcon.tsx delete mode 100644 packages/ui/src/components/OrganizationProfile/EnterpriseConnectionPage/DangerZoneSection.tsx diff --git a/.changeset/security-page-redesign.md b/.changeset/security-page-redesign.md new file mode 100644 index 00000000000..85b0e688870 --- /dev/null +++ b/.changeset/security-page-redesign.md @@ -0,0 +1,9 @@ +--- +'@clerk/localizations': minor +'@clerk/shared': minor +'@clerk/ui': minor +--- + +Update the SSO and Directory Sync sections of the `` Security page to the latest designs. Both sections now start with a "Configure" button, and SSO connection rows show the identity provider's logo and an actions menu (Edit, Continue configuration, Activate/Deactivate, Remove). These actions have been removed from the SSO connection page, and status badges are no longer color-coded. + +The SSO button uses the new `ssoSection.primaryButton__configure` localization key; `ssoSection.primaryButton__startConfiguration` is deprecated and no longer used. In `directorySyncSection`, `primaryButton__startConfiguration` is renamed to `primaryButton__configure` and `badge__unconfigured` is removed. diff --git a/packages/localizations/src/ar-SA.ts b/packages/localizations/src/ar-SA.ts index 8ecf259199e..2e5b3eb71b7 100644 --- a/packages/localizations/src/ar-SA.ts +++ b/packages/localizations/src/ar-SA.ts @@ -1386,14 +1386,13 @@ export const arSA: LocalizationResource = { badge__active: undefined, badge__inactive: undefined, badge__ssoRequired: undefined, - badge__unconfigured: undefined, description: undefined, error__load: undefined, menuAction__activate: undefined, menuAction__deactivate: undefined, menuAction__edit: undefined, menuAction__remove: undefined, - primaryButton__startConfiguration: undefined, + primaryButton__configure: undefined, removeDialog: { confirmButton: undefined, subtitle: undefined, @@ -1465,6 +1464,7 @@ export const arSA: LocalizationResource = { menuAction__edit: undefined, menuAction__remove: undefined, primaryButton__addConnection: undefined, + primaryButton__configure: undefined, primaryButton__continueConfiguration: undefined, primaryButton__startConfiguration: undefined, title: undefined, diff --git a/packages/localizations/src/be-BY.ts b/packages/localizations/src/be-BY.ts index b91d9fdb8d7..5ac87f4b6fb 100644 --- a/packages/localizations/src/be-BY.ts +++ b/packages/localizations/src/be-BY.ts @@ -1389,14 +1389,13 @@ export const beBY: LocalizationResource = { badge__active: undefined, badge__inactive: undefined, badge__ssoRequired: undefined, - badge__unconfigured: undefined, description: undefined, error__load: undefined, menuAction__activate: undefined, menuAction__deactivate: undefined, menuAction__edit: undefined, menuAction__remove: undefined, - primaryButton__startConfiguration: undefined, + primaryButton__configure: undefined, removeDialog: { confirmButton: undefined, subtitle: undefined, @@ -1468,6 +1467,7 @@ export const beBY: LocalizationResource = { menuAction__edit: undefined, menuAction__remove: undefined, primaryButton__addConnection: undefined, + primaryButton__configure: undefined, primaryButton__continueConfiguration: undefined, primaryButton__startConfiguration: undefined, title: undefined, diff --git a/packages/localizations/src/bg-BG.ts b/packages/localizations/src/bg-BG.ts index e3cae98919a..d0a497c9d71 100644 --- a/packages/localizations/src/bg-BG.ts +++ b/packages/localizations/src/bg-BG.ts @@ -1389,14 +1389,13 @@ export const bgBG: LocalizationResource = { badge__active: undefined, badge__inactive: undefined, badge__ssoRequired: undefined, - badge__unconfigured: undefined, description: undefined, error__load: undefined, menuAction__activate: undefined, menuAction__deactivate: undefined, menuAction__edit: undefined, menuAction__remove: undefined, - primaryButton__startConfiguration: undefined, + primaryButton__configure: undefined, removeDialog: { confirmButton: undefined, subtitle: undefined, @@ -1468,6 +1467,7 @@ export const bgBG: LocalizationResource = { menuAction__edit: undefined, menuAction__remove: undefined, primaryButton__addConnection: undefined, + primaryButton__configure: undefined, primaryButton__continueConfiguration: undefined, primaryButton__startConfiguration: undefined, title: undefined, diff --git a/packages/localizations/src/bn-IN.ts b/packages/localizations/src/bn-IN.ts index 43af449869d..120bae86cf2 100644 --- a/packages/localizations/src/bn-IN.ts +++ b/packages/localizations/src/bn-IN.ts @@ -1396,14 +1396,13 @@ export const bnIN: LocalizationResource = { badge__active: undefined, badge__inactive: undefined, badge__ssoRequired: undefined, - badge__unconfigured: undefined, description: undefined, error__load: undefined, menuAction__activate: undefined, menuAction__deactivate: undefined, menuAction__edit: undefined, menuAction__remove: undefined, - primaryButton__startConfiguration: undefined, + primaryButton__configure: undefined, removeDialog: { confirmButton: undefined, subtitle: undefined, @@ -1475,6 +1474,7 @@ export const bnIN: LocalizationResource = { menuAction__edit: undefined, menuAction__remove: undefined, primaryButton__addConnection: undefined, + primaryButton__configure: undefined, primaryButton__continueConfiguration: undefined, primaryButton__startConfiguration: undefined, title: undefined, diff --git a/packages/localizations/src/ca-ES.ts b/packages/localizations/src/ca-ES.ts index ae2eaa6432e..3a4b31623e2 100644 --- a/packages/localizations/src/ca-ES.ts +++ b/packages/localizations/src/ca-ES.ts @@ -1396,14 +1396,13 @@ export const caES: LocalizationResource = { badge__active: undefined, badge__inactive: undefined, badge__ssoRequired: undefined, - badge__unconfigured: undefined, description: undefined, error__load: undefined, menuAction__activate: undefined, menuAction__deactivate: undefined, menuAction__edit: undefined, menuAction__remove: undefined, - primaryButton__startConfiguration: undefined, + primaryButton__configure: undefined, removeDialog: { confirmButton: undefined, subtitle: undefined, @@ -1475,6 +1474,7 @@ export const caES: LocalizationResource = { menuAction__edit: undefined, menuAction__remove: undefined, primaryButton__addConnection: undefined, + primaryButton__configure: undefined, primaryButton__continueConfiguration: undefined, primaryButton__startConfiguration: undefined, title: undefined, diff --git a/packages/localizations/src/cs-CZ.ts b/packages/localizations/src/cs-CZ.ts index 63d0cff7de9..2071490c882 100644 --- a/packages/localizations/src/cs-CZ.ts +++ b/packages/localizations/src/cs-CZ.ts @@ -1394,14 +1394,13 @@ export const csCZ: LocalizationResource = { badge__active: undefined, badge__inactive: undefined, badge__ssoRequired: undefined, - badge__unconfigured: undefined, description: undefined, error__load: undefined, menuAction__activate: undefined, menuAction__deactivate: undefined, menuAction__edit: undefined, menuAction__remove: undefined, - primaryButton__startConfiguration: undefined, + primaryButton__configure: undefined, removeDialog: { confirmButton: undefined, subtitle: undefined, @@ -1473,6 +1472,7 @@ export const csCZ: LocalizationResource = { menuAction__edit: undefined, menuAction__remove: undefined, primaryButton__addConnection: undefined, + primaryButton__configure: undefined, primaryButton__continueConfiguration: undefined, primaryButton__startConfiguration: undefined, title: undefined, diff --git a/packages/localizations/src/da-DK.ts b/packages/localizations/src/da-DK.ts index 17de000bb61..326de38c344 100644 --- a/packages/localizations/src/da-DK.ts +++ b/packages/localizations/src/da-DK.ts @@ -1387,14 +1387,13 @@ export const daDK: LocalizationResource = { badge__active: undefined, badge__inactive: undefined, badge__ssoRequired: undefined, - badge__unconfigured: undefined, description: undefined, error__load: undefined, menuAction__activate: undefined, menuAction__deactivate: undefined, menuAction__edit: undefined, menuAction__remove: undefined, - primaryButton__startConfiguration: undefined, + primaryButton__configure: undefined, removeDialog: { confirmButton: undefined, subtitle: undefined, @@ -1466,6 +1465,7 @@ export const daDK: LocalizationResource = { menuAction__edit: undefined, menuAction__remove: undefined, primaryButton__addConnection: undefined, + primaryButton__configure: undefined, primaryButton__continueConfiguration: undefined, primaryButton__startConfiguration: undefined, title: undefined, diff --git a/packages/localizations/src/de-DE.ts b/packages/localizations/src/de-DE.ts index e78b8fc0207..872eb31515f 100644 --- a/packages/localizations/src/de-DE.ts +++ b/packages/localizations/src/de-DE.ts @@ -1402,14 +1402,13 @@ export const deDE: LocalizationResource = { badge__active: undefined, badge__inactive: undefined, badge__ssoRequired: undefined, - badge__unconfigured: undefined, description: undefined, error__load: undefined, menuAction__activate: undefined, menuAction__deactivate: undefined, menuAction__edit: undefined, menuAction__remove: undefined, - primaryButton__startConfiguration: undefined, + primaryButton__configure: undefined, removeDialog: { confirmButton: undefined, subtitle: undefined, @@ -1481,6 +1480,7 @@ export const deDE: LocalizationResource = { menuAction__edit: undefined, menuAction__remove: undefined, primaryButton__addConnection: undefined, + primaryButton__configure: undefined, primaryButton__continueConfiguration: undefined, primaryButton__startConfiguration: undefined, title: undefined, diff --git a/packages/localizations/src/el-GR.ts b/packages/localizations/src/el-GR.ts index 8af055a55ef..aad8ed971e3 100644 --- a/packages/localizations/src/el-GR.ts +++ b/packages/localizations/src/el-GR.ts @@ -1392,14 +1392,13 @@ export const elGR: LocalizationResource = { badge__active: undefined, badge__inactive: undefined, badge__ssoRequired: undefined, - badge__unconfigured: undefined, description: undefined, error__load: undefined, menuAction__activate: undefined, menuAction__deactivate: undefined, menuAction__edit: undefined, menuAction__remove: undefined, - primaryButton__startConfiguration: undefined, + primaryButton__configure: undefined, removeDialog: { confirmButton: undefined, subtitle: undefined, @@ -1471,6 +1470,7 @@ export const elGR: LocalizationResource = { menuAction__edit: undefined, menuAction__remove: undefined, primaryButton__addConnection: undefined, + primaryButton__configure: undefined, primaryButton__continueConfiguration: undefined, primaryButton__startConfiguration: undefined, title: undefined, diff --git a/packages/localizations/src/en-GB.ts b/packages/localizations/src/en-GB.ts index 4538fdf8f82..57eac3bcf29 100644 --- a/packages/localizations/src/en-GB.ts +++ b/packages/localizations/src/en-GB.ts @@ -1388,14 +1388,13 @@ export const enGB: LocalizationResource = { badge__active: undefined, badge__inactive: undefined, badge__ssoRequired: undefined, - badge__unconfigured: undefined, description: undefined, error__load: undefined, menuAction__activate: undefined, menuAction__deactivate: undefined, menuAction__edit: undefined, menuAction__remove: undefined, - primaryButton__startConfiguration: undefined, + primaryButton__configure: undefined, removeDialog: { confirmButton: undefined, subtitle: undefined, @@ -1467,6 +1466,7 @@ export const enGB: LocalizationResource = { menuAction__edit: undefined, menuAction__remove: undefined, primaryButton__addConnection: undefined, + primaryButton__configure: undefined, primaryButton__continueConfiguration: undefined, primaryButton__startConfiguration: undefined, title: undefined, diff --git a/packages/localizations/src/en-US.ts b/packages/localizations/src/en-US.ts index 4066136089a..71aab03566f 100644 --- a/packages/localizations/src/en-US.ts +++ b/packages/localizations/src/en-US.ts @@ -1425,16 +1425,14 @@ export const enUS: LocalizationResource = { directorySyncSection: { badge__active: 'Active', badge__inactive: 'Inactive', - badge__ssoRequired: 'SSO Required', - badge__unconfigured: 'Unconfigured', - description: - "Automatically add, update, and remove organization members from your identity provider's directory. Requires an SSO connection.", + badge__ssoRequired: 'SSO required', + description: 'Keep organization members synced with your identity provider. Requires an SSO connection.', error__load: 'Could not load Directory Sync', menuAction__activate: 'Activate', menuAction__deactivate: 'Deactivate', menuAction__edit: 'Edit', menuAction__remove: 'Remove', - primaryButton__startConfiguration: 'Start configuration', + primaryButton__configure: 'Configure', removeDialog: { confirmButton: 'Remove Directory Sync', subtitle: @@ -1510,6 +1508,7 @@ export const enUS: LocalizationResource = { menuAction__edit: 'Edit', menuAction__remove: 'Remove', primaryButton__addConnection: 'Add connection', + primaryButton__configure: 'Configure', primaryButton__continueConfiguration: 'Continue configuration', primaryButton__startConfiguration: 'Start configuration', title: 'SSO', diff --git a/packages/localizations/src/es-CR.ts b/packages/localizations/src/es-CR.ts index d00a4fb9e34..f5b01781654 100644 --- a/packages/localizations/src/es-CR.ts +++ b/packages/localizations/src/es-CR.ts @@ -1392,14 +1392,13 @@ export const esCR: LocalizationResource = { badge__active: undefined, badge__inactive: undefined, badge__ssoRequired: undefined, - badge__unconfigured: undefined, description: undefined, error__load: undefined, menuAction__activate: undefined, menuAction__deactivate: undefined, menuAction__edit: undefined, menuAction__remove: undefined, - primaryButton__startConfiguration: undefined, + primaryButton__configure: undefined, removeDialog: { confirmButton: undefined, subtitle: undefined, @@ -1471,6 +1470,7 @@ export const esCR: LocalizationResource = { menuAction__edit: undefined, menuAction__remove: undefined, primaryButton__addConnection: undefined, + primaryButton__configure: undefined, primaryButton__continueConfiguration: undefined, primaryButton__startConfiguration: undefined, title: undefined, diff --git a/packages/localizations/src/es-ES.ts b/packages/localizations/src/es-ES.ts index 7668b8273f2..7c65eedf5f3 100644 --- a/packages/localizations/src/es-ES.ts +++ b/packages/localizations/src/es-ES.ts @@ -1397,14 +1397,13 @@ export const esES: LocalizationResource = { badge__active: undefined, badge__inactive: undefined, badge__ssoRequired: undefined, - badge__unconfigured: undefined, description: undefined, error__load: undefined, menuAction__activate: undefined, menuAction__deactivate: undefined, menuAction__edit: undefined, menuAction__remove: undefined, - primaryButton__startConfiguration: undefined, + primaryButton__configure: undefined, removeDialog: { confirmButton: undefined, subtitle: undefined, @@ -1476,6 +1475,7 @@ export const esES: LocalizationResource = { menuAction__edit: undefined, menuAction__remove: undefined, primaryButton__addConnection: undefined, + primaryButton__configure: undefined, primaryButton__continueConfiguration: undefined, primaryButton__startConfiguration: undefined, title: undefined, diff --git a/packages/localizations/src/es-MX.ts b/packages/localizations/src/es-MX.ts index 45b270b36ee..0ed862236fc 100644 --- a/packages/localizations/src/es-MX.ts +++ b/packages/localizations/src/es-MX.ts @@ -1393,14 +1393,13 @@ export const esMX: LocalizationResource = { badge__active: undefined, badge__inactive: undefined, badge__ssoRequired: undefined, - badge__unconfigured: undefined, description: undefined, error__load: undefined, menuAction__activate: undefined, menuAction__deactivate: undefined, menuAction__edit: undefined, menuAction__remove: undefined, - primaryButton__startConfiguration: undefined, + primaryButton__configure: undefined, removeDialog: { confirmButton: undefined, subtitle: undefined, @@ -1472,6 +1471,7 @@ export const esMX: LocalizationResource = { menuAction__edit: undefined, menuAction__remove: undefined, primaryButton__addConnection: undefined, + primaryButton__configure: undefined, primaryButton__continueConfiguration: undefined, primaryButton__startConfiguration: undefined, title: undefined, diff --git a/packages/localizations/src/es-UY.ts b/packages/localizations/src/es-UY.ts index 41a07137cdf..921a5bf0d07 100644 --- a/packages/localizations/src/es-UY.ts +++ b/packages/localizations/src/es-UY.ts @@ -1391,14 +1391,13 @@ export const esUY: LocalizationResource = { badge__active: undefined, badge__inactive: undefined, badge__ssoRequired: undefined, - badge__unconfigured: undefined, description: undefined, error__load: undefined, menuAction__activate: undefined, menuAction__deactivate: undefined, menuAction__edit: undefined, menuAction__remove: undefined, - primaryButton__startConfiguration: undefined, + primaryButton__configure: undefined, removeDialog: { confirmButton: undefined, subtitle: undefined, @@ -1470,6 +1469,7 @@ export const esUY: LocalizationResource = { menuAction__edit: undefined, menuAction__remove: undefined, primaryButton__addConnection: undefined, + primaryButton__configure: undefined, primaryButton__continueConfiguration: undefined, primaryButton__startConfiguration: undefined, title: undefined, diff --git a/packages/localizations/src/fa-IR.ts b/packages/localizations/src/fa-IR.ts index 2d8ec1d212d..a15bf5980e1 100644 --- a/packages/localizations/src/fa-IR.ts +++ b/packages/localizations/src/fa-IR.ts @@ -1396,14 +1396,13 @@ export const faIR: LocalizationResource = { badge__active: undefined, badge__inactive: undefined, badge__ssoRequired: undefined, - badge__unconfigured: undefined, description: undefined, error__load: undefined, menuAction__activate: undefined, menuAction__deactivate: undefined, menuAction__edit: undefined, menuAction__remove: undefined, - primaryButton__startConfiguration: undefined, + primaryButton__configure: undefined, removeDialog: { confirmButton: undefined, subtitle: undefined, @@ -1475,6 +1474,7 @@ export const faIR: LocalizationResource = { menuAction__edit: undefined, menuAction__remove: undefined, primaryButton__addConnection: undefined, + primaryButton__configure: undefined, primaryButton__continueConfiguration: undefined, primaryButton__startConfiguration: undefined, title: undefined, diff --git a/packages/localizations/src/fi-FI.ts b/packages/localizations/src/fi-FI.ts index 82263f7b180..a4ba933013f 100644 --- a/packages/localizations/src/fi-FI.ts +++ b/packages/localizations/src/fi-FI.ts @@ -1397,14 +1397,13 @@ export const fiFI: LocalizationResource = { badge__active: undefined, badge__inactive: undefined, badge__ssoRequired: undefined, - badge__unconfigured: undefined, description: undefined, error__load: undefined, menuAction__activate: undefined, menuAction__deactivate: undefined, menuAction__edit: undefined, menuAction__remove: undefined, - primaryButton__startConfiguration: undefined, + primaryButton__configure: undefined, removeDialog: { confirmButton: undefined, subtitle: undefined, @@ -1476,6 +1475,7 @@ export const fiFI: LocalizationResource = { menuAction__edit: undefined, menuAction__remove: undefined, primaryButton__addConnection: undefined, + primaryButton__configure: undefined, primaryButton__continueConfiguration: undefined, primaryButton__startConfiguration: undefined, title: undefined, diff --git a/packages/localizations/src/fr-FR.ts b/packages/localizations/src/fr-FR.ts index 57c087c439b..1290fdb258e 100644 --- a/packages/localizations/src/fr-FR.ts +++ b/packages/localizations/src/fr-FR.ts @@ -1402,14 +1402,13 @@ export const frFR: LocalizationResource = { badge__active: undefined, badge__inactive: undefined, badge__ssoRequired: undefined, - badge__unconfigured: undefined, description: undefined, error__load: undefined, menuAction__activate: undefined, menuAction__deactivate: undefined, menuAction__edit: undefined, menuAction__remove: undefined, - primaryButton__startConfiguration: undefined, + primaryButton__configure: undefined, removeDialog: { confirmButton: undefined, subtitle: undefined, @@ -1481,6 +1480,7 @@ export const frFR: LocalizationResource = { menuAction__edit: undefined, menuAction__remove: undefined, primaryButton__addConnection: undefined, + primaryButton__configure: undefined, primaryButton__continueConfiguration: undefined, primaryButton__startConfiguration: undefined, title: undefined, diff --git a/packages/localizations/src/he-IL.ts b/packages/localizations/src/he-IL.ts index 6c66e2b782a..a3a2dea75ae 100644 --- a/packages/localizations/src/he-IL.ts +++ b/packages/localizations/src/he-IL.ts @@ -1383,14 +1383,13 @@ export const heIL: LocalizationResource = { badge__active: undefined, badge__inactive: undefined, badge__ssoRequired: undefined, - badge__unconfigured: undefined, description: undefined, error__load: undefined, menuAction__activate: undefined, menuAction__deactivate: undefined, menuAction__edit: undefined, menuAction__remove: undefined, - primaryButton__startConfiguration: undefined, + primaryButton__configure: undefined, removeDialog: { confirmButton: undefined, subtitle: undefined, @@ -1462,6 +1461,7 @@ export const heIL: LocalizationResource = { menuAction__edit: undefined, menuAction__remove: undefined, primaryButton__addConnection: undefined, + primaryButton__configure: undefined, primaryButton__continueConfiguration: undefined, primaryButton__startConfiguration: undefined, title: undefined, diff --git a/packages/localizations/src/hi-IN.ts b/packages/localizations/src/hi-IN.ts index 5495af45e4b..eea1b4492a2 100644 --- a/packages/localizations/src/hi-IN.ts +++ b/packages/localizations/src/hi-IN.ts @@ -1396,14 +1396,13 @@ export const hiIN: LocalizationResource = { badge__active: undefined, badge__inactive: undefined, badge__ssoRequired: undefined, - badge__unconfigured: undefined, description: undefined, error__load: undefined, menuAction__activate: undefined, menuAction__deactivate: undefined, menuAction__edit: undefined, menuAction__remove: undefined, - primaryButton__startConfiguration: undefined, + primaryButton__configure: undefined, removeDialog: { confirmButton: undefined, subtitle: undefined, @@ -1475,6 +1474,7 @@ export const hiIN: LocalizationResource = { menuAction__edit: undefined, menuAction__remove: undefined, primaryButton__addConnection: undefined, + primaryButton__configure: undefined, primaryButton__continueConfiguration: undefined, primaryButton__startConfiguration: undefined, title: undefined, diff --git a/packages/localizations/src/hr-HR.ts b/packages/localizations/src/hr-HR.ts index b43ad2b32a3..e20bd37f80b 100644 --- a/packages/localizations/src/hr-HR.ts +++ b/packages/localizations/src/hr-HR.ts @@ -1397,14 +1397,13 @@ export const hrHR: LocalizationResource = { badge__active: undefined, badge__inactive: undefined, badge__ssoRequired: undefined, - badge__unconfigured: undefined, description: undefined, error__load: undefined, menuAction__activate: undefined, menuAction__deactivate: undefined, menuAction__edit: undefined, menuAction__remove: undefined, - primaryButton__startConfiguration: undefined, + primaryButton__configure: undefined, removeDialog: { confirmButton: undefined, subtitle: undefined, @@ -1476,6 +1475,7 @@ export const hrHR: LocalizationResource = { menuAction__edit: undefined, menuAction__remove: undefined, primaryButton__addConnection: undefined, + primaryButton__configure: undefined, primaryButton__continueConfiguration: undefined, primaryButton__startConfiguration: undefined, title: undefined, diff --git a/packages/localizations/src/hu-HU.ts b/packages/localizations/src/hu-HU.ts index 840c05f7a30..f590be7401d 100644 --- a/packages/localizations/src/hu-HU.ts +++ b/packages/localizations/src/hu-HU.ts @@ -1398,14 +1398,13 @@ export const huHU: LocalizationResource = { badge__active: undefined, badge__inactive: undefined, badge__ssoRequired: undefined, - badge__unconfigured: undefined, description: undefined, error__load: undefined, menuAction__activate: undefined, menuAction__deactivate: undefined, menuAction__edit: undefined, menuAction__remove: undefined, - primaryButton__startConfiguration: undefined, + primaryButton__configure: undefined, removeDialog: { confirmButton: undefined, subtitle: undefined, @@ -1477,6 +1476,7 @@ export const huHU: LocalizationResource = { menuAction__edit: undefined, menuAction__remove: undefined, primaryButton__addConnection: undefined, + primaryButton__configure: undefined, primaryButton__continueConfiguration: undefined, primaryButton__startConfiguration: undefined, title: undefined, diff --git a/packages/localizations/src/id-ID.ts b/packages/localizations/src/id-ID.ts index f535eb018d4..1db9dd29c36 100644 --- a/packages/localizations/src/id-ID.ts +++ b/packages/localizations/src/id-ID.ts @@ -1390,14 +1390,13 @@ export const idID: LocalizationResource = { badge__active: undefined, badge__inactive: undefined, badge__ssoRequired: undefined, - badge__unconfigured: undefined, description: undefined, error__load: undefined, menuAction__activate: undefined, menuAction__deactivate: undefined, menuAction__edit: undefined, menuAction__remove: undefined, - primaryButton__startConfiguration: undefined, + primaryButton__configure: undefined, removeDialog: { confirmButton: undefined, subtitle: undefined, @@ -1469,6 +1468,7 @@ export const idID: LocalizationResource = { menuAction__edit: undefined, menuAction__remove: undefined, primaryButton__addConnection: undefined, + primaryButton__configure: undefined, primaryButton__continueConfiguration: undefined, primaryButton__startConfiguration: undefined, title: undefined, diff --git a/packages/localizations/src/is-IS.ts b/packages/localizations/src/is-IS.ts index b1cf4775d36..10b90661b2b 100644 --- a/packages/localizations/src/is-IS.ts +++ b/packages/localizations/src/is-IS.ts @@ -1397,14 +1397,13 @@ export const isIS: LocalizationResource = { badge__active: undefined, badge__inactive: undefined, badge__ssoRequired: undefined, - badge__unconfigured: undefined, description: undefined, error__load: undefined, menuAction__activate: undefined, menuAction__deactivate: undefined, menuAction__edit: undefined, menuAction__remove: undefined, - primaryButton__startConfiguration: undefined, + primaryButton__configure: undefined, removeDialog: { confirmButton: undefined, subtitle: undefined, @@ -1476,6 +1475,7 @@ export const isIS: LocalizationResource = { menuAction__edit: undefined, menuAction__remove: undefined, primaryButton__addConnection: undefined, + primaryButton__configure: undefined, primaryButton__continueConfiguration: undefined, primaryButton__startConfiguration: undefined, title: undefined, diff --git a/packages/localizations/src/it-IT.ts b/packages/localizations/src/it-IT.ts index 7254b4112e6..45ae11e3e6f 100644 --- a/packages/localizations/src/it-IT.ts +++ b/packages/localizations/src/it-IT.ts @@ -1397,14 +1397,13 @@ export const itIT: LocalizationResource = { badge__active: undefined, badge__inactive: undefined, badge__ssoRequired: undefined, - badge__unconfigured: undefined, description: undefined, error__load: undefined, menuAction__activate: undefined, menuAction__deactivate: undefined, menuAction__edit: undefined, menuAction__remove: undefined, - primaryButton__startConfiguration: undefined, + primaryButton__configure: undefined, removeDialog: { confirmButton: undefined, subtitle: undefined, @@ -1476,6 +1475,7 @@ export const itIT: LocalizationResource = { menuAction__edit: undefined, menuAction__remove: undefined, primaryButton__addConnection: undefined, + primaryButton__configure: undefined, primaryButton__continueConfiguration: undefined, primaryButton__startConfiguration: undefined, title: undefined, diff --git a/packages/localizations/src/ja-JP.ts b/packages/localizations/src/ja-JP.ts index 9dfeec06a4f..24a50b1f656 100644 --- a/packages/localizations/src/ja-JP.ts +++ b/packages/localizations/src/ja-JP.ts @@ -1396,14 +1396,13 @@ export const jaJP: LocalizationResource = { badge__active: undefined, badge__inactive: undefined, badge__ssoRequired: undefined, - badge__unconfigured: undefined, description: undefined, error__load: undefined, menuAction__activate: undefined, menuAction__deactivate: undefined, menuAction__edit: undefined, menuAction__remove: undefined, - primaryButton__startConfiguration: undefined, + primaryButton__configure: undefined, removeDialog: { confirmButton: undefined, subtitle: undefined, @@ -1475,6 +1474,7 @@ export const jaJP: LocalizationResource = { menuAction__edit: undefined, menuAction__remove: undefined, primaryButton__addConnection: undefined, + primaryButton__configure: undefined, primaryButton__continueConfiguration: undefined, primaryButton__startConfiguration: undefined, title: undefined, diff --git a/packages/localizations/src/kk-KZ.ts b/packages/localizations/src/kk-KZ.ts index 34fabe33f2d..54a92ca76cc 100644 --- a/packages/localizations/src/kk-KZ.ts +++ b/packages/localizations/src/kk-KZ.ts @@ -1383,14 +1383,13 @@ export const kkKZ: LocalizationResource = { badge__active: undefined, badge__inactive: undefined, badge__ssoRequired: undefined, - badge__unconfigured: undefined, description: undefined, error__load: undefined, menuAction__activate: undefined, menuAction__deactivate: undefined, menuAction__edit: undefined, menuAction__remove: undefined, - primaryButton__startConfiguration: undefined, + primaryButton__configure: undefined, removeDialog: { confirmButton: undefined, subtitle: undefined, @@ -1462,6 +1461,7 @@ export const kkKZ: LocalizationResource = { menuAction__edit: undefined, menuAction__remove: undefined, primaryButton__addConnection: undefined, + primaryButton__configure: undefined, primaryButton__continueConfiguration: undefined, primaryButton__startConfiguration: undefined, title: undefined, diff --git a/packages/localizations/src/ko-KR.ts b/packages/localizations/src/ko-KR.ts index 0c1326fc0fc..bb36f00f23d 100644 --- a/packages/localizations/src/ko-KR.ts +++ b/packages/localizations/src/ko-KR.ts @@ -1388,14 +1388,13 @@ export const koKR: LocalizationResource = { badge__active: undefined, badge__inactive: undefined, badge__ssoRequired: undefined, - badge__unconfigured: undefined, description: undefined, error__load: undefined, menuAction__activate: undefined, menuAction__deactivate: undefined, menuAction__edit: undefined, menuAction__remove: undefined, - primaryButton__startConfiguration: undefined, + primaryButton__configure: undefined, removeDialog: { confirmButton: undefined, subtitle: undefined, @@ -1467,6 +1466,7 @@ export const koKR: LocalizationResource = { menuAction__edit: undefined, menuAction__remove: undefined, primaryButton__addConnection: undefined, + primaryButton__configure: undefined, primaryButton__continueConfiguration: undefined, primaryButton__startConfiguration: undefined, title: undefined, diff --git a/packages/localizations/src/mn-MN.ts b/packages/localizations/src/mn-MN.ts index eb3f619b3bc..d9efbde31ea 100644 --- a/packages/localizations/src/mn-MN.ts +++ b/packages/localizations/src/mn-MN.ts @@ -1390,14 +1390,13 @@ export const mnMN: LocalizationResource = { badge__active: undefined, badge__inactive: undefined, badge__ssoRequired: undefined, - badge__unconfigured: undefined, description: undefined, error__load: undefined, menuAction__activate: undefined, menuAction__deactivate: undefined, menuAction__edit: undefined, menuAction__remove: undefined, - primaryButton__startConfiguration: undefined, + primaryButton__configure: undefined, removeDialog: { confirmButton: undefined, subtitle: undefined, @@ -1469,6 +1468,7 @@ export const mnMN: LocalizationResource = { menuAction__edit: undefined, menuAction__remove: undefined, primaryButton__addConnection: undefined, + primaryButton__configure: undefined, primaryButton__continueConfiguration: undefined, primaryButton__startConfiguration: undefined, title: undefined, diff --git a/packages/localizations/src/ms-MY.ts b/packages/localizations/src/ms-MY.ts index 17c20e97493..aae0947fd24 100644 --- a/packages/localizations/src/ms-MY.ts +++ b/packages/localizations/src/ms-MY.ts @@ -1399,14 +1399,13 @@ export const msMY: LocalizationResource = { badge__active: undefined, badge__inactive: undefined, badge__ssoRequired: undefined, - badge__unconfigured: undefined, description: undefined, error__load: undefined, menuAction__activate: undefined, menuAction__deactivate: undefined, menuAction__edit: undefined, menuAction__remove: undefined, - primaryButton__startConfiguration: undefined, + primaryButton__configure: undefined, removeDialog: { confirmButton: undefined, subtitle: undefined, @@ -1478,6 +1477,7 @@ export const msMY: LocalizationResource = { menuAction__edit: undefined, menuAction__remove: undefined, primaryButton__addConnection: undefined, + primaryButton__configure: undefined, primaryButton__continueConfiguration: undefined, primaryButton__startConfiguration: undefined, title: undefined, diff --git a/packages/localizations/src/nb-NO.ts b/packages/localizations/src/nb-NO.ts index 24bb5be3b7f..fb21d0f6144 100644 --- a/packages/localizations/src/nb-NO.ts +++ b/packages/localizations/src/nb-NO.ts @@ -1398,14 +1398,13 @@ export const nbNO: LocalizationResource = { badge__active: undefined, badge__inactive: undefined, badge__ssoRequired: undefined, - badge__unconfigured: undefined, description: undefined, error__load: undefined, menuAction__activate: undefined, menuAction__deactivate: undefined, menuAction__edit: undefined, menuAction__remove: undefined, - primaryButton__startConfiguration: undefined, + primaryButton__configure: undefined, removeDialog: { confirmButton: undefined, subtitle: undefined, @@ -1477,6 +1476,7 @@ export const nbNO: LocalizationResource = { menuAction__edit: undefined, menuAction__remove: undefined, primaryButton__addConnection: undefined, + primaryButton__configure: undefined, primaryButton__continueConfiguration: undefined, primaryButton__startConfiguration: undefined, title: undefined, diff --git a/packages/localizations/src/nl-BE.ts b/packages/localizations/src/nl-BE.ts index b12667e42a6..218df0681e4 100644 --- a/packages/localizations/src/nl-BE.ts +++ b/packages/localizations/src/nl-BE.ts @@ -1390,14 +1390,13 @@ export const nlBE: LocalizationResource = { badge__active: undefined, badge__inactive: undefined, badge__ssoRequired: undefined, - badge__unconfigured: undefined, description: undefined, error__load: undefined, menuAction__activate: undefined, menuAction__deactivate: undefined, menuAction__edit: undefined, menuAction__remove: undefined, - primaryButton__startConfiguration: undefined, + primaryButton__configure: undefined, removeDialog: { confirmButton: undefined, subtitle: undefined, @@ -1469,6 +1468,7 @@ export const nlBE: LocalizationResource = { menuAction__edit: undefined, menuAction__remove: undefined, primaryButton__addConnection: undefined, + primaryButton__configure: undefined, primaryButton__continueConfiguration: undefined, primaryButton__startConfiguration: undefined, title: undefined, diff --git a/packages/localizations/src/nl-NL.ts b/packages/localizations/src/nl-NL.ts index 827f26616d6..2c6a06c884f 100644 --- a/packages/localizations/src/nl-NL.ts +++ b/packages/localizations/src/nl-NL.ts @@ -1390,14 +1390,13 @@ export const nlNL: LocalizationResource = { badge__active: undefined, badge__inactive: undefined, badge__ssoRequired: undefined, - badge__unconfigured: undefined, description: undefined, error__load: undefined, menuAction__activate: undefined, menuAction__deactivate: undefined, menuAction__edit: undefined, menuAction__remove: undefined, - primaryButton__startConfiguration: undefined, + primaryButton__configure: undefined, removeDialog: { confirmButton: undefined, subtitle: undefined, @@ -1469,6 +1468,7 @@ export const nlNL: LocalizationResource = { menuAction__edit: undefined, menuAction__remove: undefined, primaryButton__addConnection: undefined, + primaryButton__configure: undefined, primaryButton__continueConfiguration: undefined, primaryButton__startConfiguration: undefined, title: undefined, diff --git a/packages/localizations/src/pl-PL.ts b/packages/localizations/src/pl-PL.ts index 629ae7230be..03c6d1721e1 100644 --- a/packages/localizations/src/pl-PL.ts +++ b/packages/localizations/src/pl-PL.ts @@ -1388,14 +1388,13 @@ export const plPL: LocalizationResource = { badge__active: undefined, badge__inactive: undefined, badge__ssoRequired: undefined, - badge__unconfigured: undefined, description: undefined, error__load: undefined, menuAction__activate: undefined, menuAction__deactivate: undefined, menuAction__edit: undefined, menuAction__remove: undefined, - primaryButton__startConfiguration: undefined, + primaryButton__configure: undefined, removeDialog: { confirmButton: undefined, subtitle: undefined, @@ -1467,6 +1466,7 @@ export const plPL: LocalizationResource = { menuAction__edit: undefined, menuAction__remove: undefined, primaryButton__addConnection: undefined, + primaryButton__configure: undefined, primaryButton__continueConfiguration: undefined, primaryButton__startConfiguration: undefined, title: undefined, diff --git a/packages/localizations/src/pt-BR.ts b/packages/localizations/src/pt-BR.ts index 764bb071051..3266762b85a 100644 --- a/packages/localizations/src/pt-BR.ts +++ b/packages/localizations/src/pt-BR.ts @@ -1398,14 +1398,13 @@ export const ptBR: LocalizationResource = { badge__active: undefined, badge__inactive: undefined, badge__ssoRequired: undefined, - badge__unconfigured: undefined, description: undefined, error__load: undefined, menuAction__activate: undefined, menuAction__deactivate: undefined, menuAction__edit: undefined, menuAction__remove: undefined, - primaryButton__startConfiguration: undefined, + primaryButton__configure: undefined, removeDialog: { confirmButton: undefined, subtitle: undefined, @@ -1477,6 +1476,7 @@ export const ptBR: LocalizationResource = { menuAction__edit: undefined, menuAction__remove: undefined, primaryButton__addConnection: undefined, + primaryButton__configure: undefined, primaryButton__continueConfiguration: undefined, primaryButton__startConfiguration: undefined, title: undefined, diff --git a/packages/localizations/src/pt-PT.ts b/packages/localizations/src/pt-PT.ts index 9c29d487a27..28a9b532dbb 100644 --- a/packages/localizations/src/pt-PT.ts +++ b/packages/localizations/src/pt-PT.ts @@ -1398,14 +1398,13 @@ export const ptPT: LocalizationResource = { badge__active: undefined, badge__inactive: undefined, badge__ssoRequired: undefined, - badge__unconfigured: undefined, description: undefined, error__load: undefined, menuAction__activate: undefined, menuAction__deactivate: undefined, menuAction__edit: undefined, menuAction__remove: undefined, - primaryButton__startConfiguration: undefined, + primaryButton__configure: undefined, removeDialog: { confirmButton: undefined, subtitle: undefined, @@ -1477,6 +1476,7 @@ export const ptPT: LocalizationResource = { menuAction__edit: undefined, menuAction__remove: undefined, primaryButton__addConnection: undefined, + primaryButton__configure: undefined, primaryButton__continueConfiguration: undefined, primaryButton__startConfiguration: undefined, title: undefined, diff --git a/packages/localizations/src/ro-RO.ts b/packages/localizations/src/ro-RO.ts index 43268667827..3fd1ec36e24 100644 --- a/packages/localizations/src/ro-RO.ts +++ b/packages/localizations/src/ro-RO.ts @@ -1398,14 +1398,13 @@ export const roRO: LocalizationResource = { badge__active: undefined, badge__inactive: undefined, badge__ssoRequired: undefined, - badge__unconfigured: undefined, description: undefined, error__load: undefined, menuAction__activate: undefined, menuAction__deactivate: undefined, menuAction__edit: undefined, menuAction__remove: undefined, - primaryButton__startConfiguration: undefined, + primaryButton__configure: undefined, removeDialog: { confirmButton: undefined, subtitle: undefined, @@ -1477,6 +1476,7 @@ export const roRO: LocalizationResource = { menuAction__edit: undefined, menuAction__remove: undefined, primaryButton__addConnection: undefined, + primaryButton__configure: undefined, primaryButton__continueConfiguration: undefined, primaryButton__startConfiguration: undefined, title: undefined, diff --git a/packages/localizations/src/ru-RU.ts b/packages/localizations/src/ru-RU.ts index 4664a748889..dad37d96544 100644 --- a/packages/localizations/src/ru-RU.ts +++ b/packages/localizations/src/ru-RU.ts @@ -1392,14 +1392,13 @@ export const ruRU: LocalizationResource = { badge__active: undefined, badge__inactive: undefined, badge__ssoRequired: undefined, - badge__unconfigured: undefined, description: undefined, error__load: undefined, menuAction__activate: undefined, menuAction__deactivate: undefined, menuAction__edit: undefined, menuAction__remove: undefined, - primaryButton__startConfiguration: undefined, + primaryButton__configure: undefined, removeDialog: { confirmButton: undefined, subtitle: undefined, @@ -1471,6 +1470,7 @@ export const ruRU: LocalizationResource = { menuAction__edit: undefined, menuAction__remove: undefined, primaryButton__addConnection: undefined, + primaryButton__configure: undefined, primaryButton__continueConfiguration: undefined, primaryButton__startConfiguration: undefined, title: undefined, diff --git a/packages/localizations/src/sk-SK.ts b/packages/localizations/src/sk-SK.ts index 742e6ec56ba..88b70f51957 100644 --- a/packages/localizations/src/sk-SK.ts +++ b/packages/localizations/src/sk-SK.ts @@ -1388,14 +1388,13 @@ export const skSK: LocalizationResource = { badge__active: undefined, badge__inactive: undefined, badge__ssoRequired: undefined, - badge__unconfigured: undefined, description: undefined, error__load: undefined, menuAction__activate: undefined, menuAction__deactivate: undefined, menuAction__edit: undefined, menuAction__remove: undefined, - primaryButton__startConfiguration: undefined, + primaryButton__configure: undefined, removeDialog: { confirmButton: undefined, subtitle: undefined, @@ -1467,6 +1466,7 @@ export const skSK: LocalizationResource = { menuAction__edit: undefined, menuAction__remove: undefined, primaryButton__addConnection: undefined, + primaryButton__configure: undefined, primaryButton__continueConfiguration: undefined, primaryButton__startConfiguration: undefined, title: undefined, diff --git a/packages/localizations/src/sr-RS.ts b/packages/localizations/src/sr-RS.ts index c09369a7cf8..7afd79fce49 100644 --- a/packages/localizations/src/sr-RS.ts +++ b/packages/localizations/src/sr-RS.ts @@ -1388,14 +1388,13 @@ export const srRS: LocalizationResource = { badge__active: undefined, badge__inactive: undefined, badge__ssoRequired: undefined, - badge__unconfigured: undefined, description: undefined, error__load: undefined, menuAction__activate: undefined, menuAction__deactivate: undefined, menuAction__edit: undefined, menuAction__remove: undefined, - primaryButton__startConfiguration: undefined, + primaryButton__configure: undefined, removeDialog: { confirmButton: undefined, subtitle: undefined, @@ -1467,6 +1466,7 @@ export const srRS: LocalizationResource = { menuAction__edit: undefined, menuAction__remove: undefined, primaryButton__addConnection: undefined, + primaryButton__configure: undefined, primaryButton__continueConfiguration: undefined, primaryButton__startConfiguration: undefined, title: undefined, diff --git a/packages/localizations/src/sv-SE.ts b/packages/localizations/src/sv-SE.ts index 508866d8765..1537c1673fd 100644 --- a/packages/localizations/src/sv-SE.ts +++ b/packages/localizations/src/sv-SE.ts @@ -1388,14 +1388,13 @@ export const svSE: LocalizationResource = { badge__active: undefined, badge__inactive: undefined, badge__ssoRequired: undefined, - badge__unconfigured: undefined, description: undefined, error__load: undefined, menuAction__activate: undefined, menuAction__deactivate: undefined, menuAction__edit: undefined, menuAction__remove: undefined, - primaryButton__startConfiguration: undefined, + primaryButton__configure: undefined, removeDialog: { confirmButton: undefined, subtitle: undefined, @@ -1467,6 +1466,7 @@ export const svSE: LocalizationResource = { menuAction__edit: undefined, menuAction__remove: undefined, primaryButton__addConnection: undefined, + primaryButton__configure: undefined, primaryButton__continueConfiguration: undefined, primaryButton__startConfiguration: undefined, title: undefined, diff --git a/packages/localizations/src/ta-IN.ts b/packages/localizations/src/ta-IN.ts index de419b38460..c3b601cdb76 100644 --- a/packages/localizations/src/ta-IN.ts +++ b/packages/localizations/src/ta-IN.ts @@ -1401,14 +1401,13 @@ export const taIN: LocalizationResource = { badge__active: undefined, badge__inactive: undefined, badge__ssoRequired: undefined, - badge__unconfigured: undefined, description: undefined, error__load: undefined, menuAction__activate: undefined, menuAction__deactivate: undefined, menuAction__edit: undefined, menuAction__remove: undefined, - primaryButton__startConfiguration: undefined, + primaryButton__configure: undefined, removeDialog: { confirmButton: undefined, subtitle: undefined, @@ -1480,6 +1479,7 @@ export const taIN: LocalizationResource = { menuAction__edit: undefined, menuAction__remove: undefined, primaryButton__addConnection: undefined, + primaryButton__configure: undefined, primaryButton__continueConfiguration: undefined, primaryButton__startConfiguration: undefined, title: undefined, diff --git a/packages/localizations/src/te-IN.ts b/packages/localizations/src/te-IN.ts index c5dcaaafd3b..b2884dd6d00 100644 --- a/packages/localizations/src/te-IN.ts +++ b/packages/localizations/src/te-IN.ts @@ -1398,14 +1398,13 @@ export const teIN: LocalizationResource = { badge__active: undefined, badge__inactive: undefined, badge__ssoRequired: undefined, - badge__unconfigured: undefined, description: undefined, error__load: undefined, menuAction__activate: undefined, menuAction__deactivate: undefined, menuAction__edit: undefined, menuAction__remove: undefined, - primaryButton__startConfiguration: undefined, + primaryButton__configure: undefined, removeDialog: { confirmButton: undefined, subtitle: undefined, @@ -1477,6 +1476,7 @@ export const teIN: LocalizationResource = { menuAction__edit: undefined, menuAction__remove: undefined, primaryButton__addConnection: undefined, + primaryButton__configure: undefined, primaryButton__continueConfiguration: undefined, primaryButton__startConfiguration: undefined, title: undefined, diff --git a/packages/localizations/src/th-TH.ts b/packages/localizations/src/th-TH.ts index 9c966c37b22..d3554331111 100644 --- a/packages/localizations/src/th-TH.ts +++ b/packages/localizations/src/th-TH.ts @@ -1389,14 +1389,13 @@ export const thTH: LocalizationResource = { badge__active: undefined, badge__inactive: undefined, badge__ssoRequired: undefined, - badge__unconfigured: undefined, description: undefined, error__load: undefined, menuAction__activate: undefined, menuAction__deactivate: undefined, menuAction__edit: undefined, menuAction__remove: undefined, - primaryButton__startConfiguration: undefined, + primaryButton__configure: undefined, removeDialog: { confirmButton: undefined, subtitle: undefined, @@ -1468,6 +1467,7 @@ export const thTH: LocalizationResource = { menuAction__edit: undefined, menuAction__remove: undefined, primaryButton__addConnection: undefined, + primaryButton__configure: undefined, primaryButton__continueConfiguration: undefined, primaryButton__startConfiguration: undefined, title: undefined, diff --git a/packages/localizations/src/tr-TR.ts b/packages/localizations/src/tr-TR.ts index f91f29111d8..0a9a81a7bb8 100644 --- a/packages/localizations/src/tr-TR.ts +++ b/packages/localizations/src/tr-TR.ts @@ -1388,14 +1388,13 @@ export const trTR: LocalizationResource = { badge__active: undefined, badge__inactive: undefined, badge__ssoRequired: undefined, - badge__unconfigured: undefined, description: undefined, error__load: undefined, menuAction__activate: undefined, menuAction__deactivate: undefined, menuAction__edit: undefined, menuAction__remove: undefined, - primaryButton__startConfiguration: undefined, + primaryButton__configure: undefined, removeDialog: { confirmButton: undefined, subtitle: undefined, @@ -1467,6 +1466,7 @@ export const trTR: LocalizationResource = { menuAction__edit: undefined, menuAction__remove: undefined, primaryButton__addConnection: undefined, + primaryButton__configure: undefined, primaryButton__continueConfiguration: undefined, primaryButton__startConfiguration: undefined, title: undefined, diff --git a/packages/localizations/src/uk-UA.ts b/packages/localizations/src/uk-UA.ts index fe89a0e14ea..8a385aca92d 100644 --- a/packages/localizations/src/uk-UA.ts +++ b/packages/localizations/src/uk-UA.ts @@ -1388,14 +1388,13 @@ export const ukUA: LocalizationResource = { badge__active: undefined, badge__inactive: undefined, badge__ssoRequired: undefined, - badge__unconfigured: undefined, description: undefined, error__load: undefined, menuAction__activate: undefined, menuAction__deactivate: undefined, menuAction__edit: undefined, menuAction__remove: undefined, - primaryButton__startConfiguration: undefined, + primaryButton__configure: undefined, removeDialog: { confirmButton: undefined, subtitle: undefined, @@ -1467,6 +1466,7 @@ export const ukUA: LocalizationResource = { menuAction__edit: undefined, menuAction__remove: undefined, primaryButton__addConnection: undefined, + primaryButton__configure: undefined, primaryButton__continueConfiguration: undefined, primaryButton__startConfiguration: undefined, title: undefined, diff --git a/packages/localizations/src/vi-VN.ts b/packages/localizations/src/vi-VN.ts index 1cb2a822051..453c8f13419 100644 --- a/packages/localizations/src/vi-VN.ts +++ b/packages/localizations/src/vi-VN.ts @@ -1396,14 +1396,13 @@ export const viVN: LocalizationResource = { badge__active: undefined, badge__inactive: undefined, badge__ssoRequired: undefined, - badge__unconfigured: undefined, description: undefined, error__load: undefined, menuAction__activate: undefined, menuAction__deactivate: undefined, menuAction__edit: undefined, menuAction__remove: undefined, - primaryButton__startConfiguration: undefined, + primaryButton__configure: undefined, removeDialog: { confirmButton: undefined, subtitle: undefined, @@ -1475,6 +1474,7 @@ export const viVN: LocalizationResource = { menuAction__edit: undefined, menuAction__remove: undefined, primaryButton__addConnection: undefined, + primaryButton__configure: undefined, primaryButton__continueConfiguration: undefined, primaryButton__startConfiguration: undefined, title: undefined, diff --git a/packages/localizations/src/zh-CN.ts b/packages/localizations/src/zh-CN.ts index 2b64031e69c..27a9f77859d 100644 --- a/packages/localizations/src/zh-CN.ts +++ b/packages/localizations/src/zh-CN.ts @@ -1381,14 +1381,13 @@ export const zhCN: LocalizationResource = { badge__active: undefined, badge__inactive: undefined, badge__ssoRequired: undefined, - badge__unconfigured: undefined, description: undefined, error__load: undefined, menuAction__activate: undefined, menuAction__deactivate: undefined, menuAction__edit: undefined, menuAction__remove: undefined, - primaryButton__startConfiguration: undefined, + primaryButton__configure: undefined, removeDialog: { confirmButton: undefined, subtitle: undefined, @@ -1460,6 +1459,7 @@ export const zhCN: LocalizationResource = { menuAction__edit: undefined, menuAction__remove: undefined, primaryButton__addConnection: undefined, + primaryButton__configure: undefined, primaryButton__continueConfiguration: undefined, primaryButton__startConfiguration: undefined, title: undefined, diff --git a/packages/localizations/src/zh-TW.ts b/packages/localizations/src/zh-TW.ts index 847b62ead44..6e93987bdf7 100644 --- a/packages/localizations/src/zh-TW.ts +++ b/packages/localizations/src/zh-TW.ts @@ -1384,14 +1384,13 @@ export const zhTW: LocalizationResource = { badge__active: undefined, badge__inactive: undefined, badge__ssoRequired: undefined, - badge__unconfigured: undefined, description: undefined, error__load: undefined, menuAction__activate: undefined, menuAction__deactivate: undefined, menuAction__edit: undefined, menuAction__remove: undefined, - primaryButton__startConfiguration: undefined, + primaryButton__configure: undefined, removeDialog: { confirmButton: undefined, subtitle: undefined, @@ -1463,6 +1462,7 @@ export const zhTW: LocalizationResource = { menuAction__edit: undefined, menuAction__remove: undefined, primaryButton__addConnection: undefined, + primaryButton__configure: undefined, primaryButton__continueConfiguration: undefined, primaryButton__startConfiguration: undefined, title: undefined, diff --git a/packages/shared/src/types/localization.ts b/packages/shared/src/types/localization.ts index 6d2c93a776d..947e0150904 100644 --- a/packages/shared/src/types/localization.ts +++ b/packages/shared/src/types/localization.ts @@ -1255,7 +1255,11 @@ export type __internal_LocalizationResource = { badge__active: LocalizationValue; badge__inactive: LocalizationValue; descriptionLine1: LocalizationValue; + /** + * @deprecated Use `primaryButton__configure` instead. + */ primaryButton__startConfiguration: LocalizationValue; + primaryButton__configure: LocalizationValue; primaryButton__continueConfiguration: LocalizationValue; primaryButton__addConnection: LocalizationValue; domainLabel: LocalizationValue; @@ -1332,13 +1336,12 @@ export type __internal_LocalizationResource = { }; directorySyncSection: { title: LocalizationValue; - badge__unconfigured: LocalizationValue; badge__ssoRequired: LocalizationValue; badge__active: LocalizationValue; badge__inactive: LocalizationValue; description: LocalizationValue; error__load: LocalizationValue; - primaryButton__startConfiguration: LocalizationValue; + primaryButton__configure: LocalizationValue; menuAction__edit: LocalizationValue; menuAction__activate: LocalizationValue; menuAction__deactivate: LocalizationValue; diff --git a/packages/ui/src/components/ConfigureDirectorySync/SecurityDirectorySyncSection.tsx b/packages/ui/src/components/ConfigureDirectorySync/SecurityDirectorySyncSection.tsx index 32e333957d2..7d76899ece4 100644 --- a/packages/ui/src/components/ConfigureDirectorySync/SecurityDirectorySyncSection.tsx +++ b/packages/ui/src/components/ConfigureDirectorySync/SecurityDirectorySyncSection.tsx @@ -9,10 +9,11 @@ import { Card } from '@/ui/elements/Card'; import { CardStateProvider, useCardState } from '@/ui/elements/contexts'; import { ProfileSection } from '@/ui/elements/Section'; import { ThreeDotsMenu } from '@/ui/elements/ThreeDotsMenu'; +import type { ThemableCssProp } from '@/ui/styledSystem'; import { handleError } from '@/utils/errorHandler'; import type { LocalizationKey } from '../../customizables'; -import { Badge, Button, Col, descriptors, Flex, localizationKeys, Spinner, Text } from '../../customizables'; +import { Badge, Col, descriptors, Flex, localizationKeys, Spinner, Text } from '../../customizables'; import { sortEnterpriseConnections } from '../ConfigureSSO/domain/organizationEnterpriseConnection'; import { ResetConnectionDialog } from '../ConfigureSSO/ResetConnectionDialog'; @@ -25,19 +26,15 @@ type SecurityDirectorySyncSectionProps = { type DirectorySyncStatus = 'unconfigured' | 'active' | 'inactive'; const STATUS_BADGES: Record< - DirectorySyncStatus, + Exclude, { colorScheme: 'primary' | 'success' | 'warning'; label: LocalizationKey } > = { - unconfigured: { - colorScheme: 'primary', - label: localizationKeys('organizationProfile.securityPage.directorySyncSection.badge__unconfigured'), - }, active: { - colorScheme: 'success', + colorScheme: 'primary', label: localizationKeys('organizationProfile.securityPage.directorySyncSection.badge__active'), }, inactive: { - colorScheme: 'warning', + colorScheme: 'primary', label: localizationKeys('organizationProfile.securityPage.directorySyncSection.badge__inactive'), }, }; @@ -71,24 +68,14 @@ export const SecurityDirectorySyncSection = ({ // The hook maps a 404 (no directory yet) to `data: null`, so any error here is unexpected. const isLoading = isLoadingConnections || (Boolean(connection) && isLoadingDirectory); const error = connectionsError ?? directoryError; - const isSettled = !isLoading && !error; const status: DirectorySyncStatus = directory ? (directory.enabled ? 'active' : 'inactive') : 'unconfigured'; - const badge = STATUS_BADGES[status]; return ( - ) : undefined - } > {isLoading ? ( - - - + {card.error} + + {actions && ( + setIsRemoveDialogOpen(false)} + confirmationValue={organizationName} + title={localizationKeys('organizationProfile.securityPage.removeDialog.title')} + subtitle={localizationKeys('organizationProfile.securityPage.removeDialog.subtitle', { + name: connection.name, + })} + confirmButtonLabel={localizationKeys('organizationProfile.securityPage.removeDialog.confirmButton')} + onDelete={() => deleteConnection(connection.id)} + contentRef={contentRef} + /> + )} + ); }; -const SsoDescription = (): JSX.Element => ( +const SsoDescription = ({ sx }: { sx?: ThemableCssProp }): JSX.Element => ( ); diff --git a/packages/ui/src/components/OrganizationProfile/__tests__/EnterpriseConnectionPage.test.tsx b/packages/ui/src/components/OrganizationProfile/__tests__/EnterpriseConnectionPage.test.tsx index bc5d85c0843..004f1677179 100644 --- a/packages/ui/src/components/OrganizationProfile/__tests__/EnterpriseConnectionPage.test.tsx +++ b/packages/ui/src/components/OrganizationProfile/__tests__/EnterpriseConnectionPage.test.tsx @@ -87,16 +87,12 @@ const renderPage = ( fixtures: any, connection: any, onBack = vi.fn(), - onOpenWizard = vi.fn(), ) => { const page = (next: any) => ( ); @@ -104,7 +100,6 @@ const renderPage = ( return { onBack, - onOpenWizard, ...result, rerenderWith: (next: any) => result.rerender(page(next)), }; @@ -132,8 +127,8 @@ describe('EnterpriseConnectionPage', () => { expect(screen.getByText('Service provider')).toBeInTheDocument(); expect(screen.getByText('Identity provider')).toBeInTheDocument(); expect(screen.getByText('Settings')).toBeInTheDocument(); - expect(screen.getByText('Danger zone')).toBeInTheDocument(); - expect(screen.getByRole('button', { name: 'Remove connection' })).toBeInTheDocument(); + expect(screen.queryByText('Danger zone')).not.toBeInTheDocument(); + expect(screen.queryByRole('button', { name: 'Remove connection' })).not.toBeInTheDocument(); expect(screen.getByDisplayValue('https://accounts.clerk.com/v1/acs')).toBeInTheDocument(); expect(screen.getByDisplayValue('https://accounts.clerk.com/saml/ent_1')).toBeInTheDocument(); @@ -231,97 +226,22 @@ describe('EnterpriseConnectionPage', () => { }); }); - describe('header actions', () => { - it('offers no header action for an active connection', async () => { + describe('header', () => { + it.each([ + ['active', { active: true }], + ['inactive', { active: false }], + ['mid-setup', { samlConnection: null, oauthConfig: null }], + ])('offers no lifecycle actions for a %s connection', async (_, overrides) => { const { wrapper, fixtures } = await createFixtures(withPageFixtures); withNoTestRuns(fixtures); - renderPage(wrapper, fixtures, samlConnection({ active: true })); + renderPage(wrapper, fixtures, samlConnection(overrides)); expect(await screen.findByRole('heading', { name: 'clerk.com' })).toBeInTheDocument(); expect(screen.queryByRole('button', { name: 'Activate' })).not.toBeInTheDocument(); - expect(screen.queryByRole('button', { name: 'Deactivate' })).not.toBeInTheDocument(); expect(screen.queryByRole('button', { name: 'Continue setup' })).not.toBeInTheDocument(); - }); - - it('activates an inactive connection', async () => { - const { wrapper, fixtures } = await createFixtures(withPageFixtures); - withNoTestRuns(fixtures); - fixtures.clerk.organization?.getEnterpriseConnectionTestRuns.mockResolvedValue({ - data: [{ id: 'run_1', status: 'success' }], - total_count: 1, - } as any); - fixtures.clerk.organization?.updateEnterpriseConnection.mockResolvedValue({ active: true } as any); - - const { userEvent } = renderPage(wrapper, fixtures, samlConnection({ active: false })); - - await userEvent.click(await screen.findByRole('button', { name: 'Activate' })); - - expect(fixtures.clerk.organization?.updateEnterpriseConnection).toHaveBeenCalledWith('ent_1', { active: true }); - }); - - it('offers Continue setup for a connection that is still mid-setup', async () => { - const { wrapper, fixtures } = await createFixtures(withPageFixtures); - withNoTestRuns(fixtures); - - const { userEvent, onOpenWizard } = renderPage( - wrapper, - fixtures, - samlConnection({ samlConnection: null, oauthConfig: null }), - ); - - await userEvent.click(await screen.findByRole('button', { name: 'Continue setup' })); - - expect(onOpenWizard).toHaveBeenCalled(); - expect(screen.queryByRole('button', { name: 'Open setup wizard' })).not.toBeInTheDocument(); - }); - }); - - describe('danger zone', () => { - it('deactivates an active connection', async () => { - const { wrapper, fixtures } = await createFixtures(withPageFixtures); - withNoTestRuns(fixtures); - fixtures.clerk.organization?.updateEnterpriseConnection.mockResolvedValue({ active: false } as any); - - const { userEvent } = renderPage(wrapper, fixtures, samlConnection({ active: true })); - - await userEvent.click(await screen.findByRole('button', { name: 'Deactivate connection' })); - - expect(fixtures.clerk.organization?.updateEnterpriseConnection).toHaveBeenCalledWith('ent_1', { active: false }); - }); - - it('offers no Deactivate connection button for an inactive connection', async () => { - const { wrapper, fixtures } = await createFixtures(withPageFixtures); - withNoTestRuns(fixtures); - - renderPage(wrapper, fixtures, samlConnection({ active: false })); - - expect(await screen.findByRole('button', { name: 'Remove connection' })).toBeInTheDocument(); expect(screen.queryByRole('button', { name: 'Deactivate connection' })).not.toBeInTheDocument(); - }); - - it('removes the connection from the danger zone and returns to the overview', async () => { - const { wrapper, fixtures } = await createFixtures(withPageFixtures); - withNoTestRuns(fixtures); - fixtures.clerk.organization?.deleteEnterpriseConnection.mockResolvedValue({} as any); - - const { userEvent, onBack } = renderPage(wrapper, fixtures, samlConnection({ active: true })); - - expect(await screen.findAllByRole('button', { name: 'Remove connection' })).toHaveLength(1); - await userEvent.click(screen.getByRole('button', { name: 'Remove connection' })); - - const dialog = within(await screen.findByRole('dialog')); - expect(dialog.getByRole('heading', { name: 'Remove SSO connection' })).toBeInTheDocument(); - expect(dialog.getByText(/Are you sure you want to remove the connection "clerk.com"\?/i)).toBeInTheDocument(); - - await userEvent.type(dialog.getByLabelText(/below to continue/i), 'Org1'); - await waitFor(() => expect(dialog.getByRole('button', { name: 'Remove connection' })).toBeEnabled()); - await userEvent.click(dialog.getByRole('button', { name: 'Remove connection' })); - - await waitFor(() => { - expect(fixtures.clerk.organization?.deleteEnterpriseConnection).toHaveBeenCalledWith('ent_1'); - }); - expect(onBack).toHaveBeenCalled(); + expect(screen.queryByRole('button', { name: 'Remove connection' })).not.toBeInTheDocument(); }); }); diff --git a/packages/ui/src/components/OrganizationProfile/__tests__/OrganizationProfile.test.tsx b/packages/ui/src/components/OrganizationProfile/__tests__/OrganizationProfile.test.tsx index 0027468d9e1..cc8799f07ad 100644 --- a/packages/ui/src/components/OrganizationProfile/__tests__/OrganizationProfile.test.tsx +++ b/packages/ui/src/components/OrganizationProfile/__tests__/OrganizationProfile.test.tsx @@ -594,7 +594,7 @@ describe('OrganizationProfile', () => { renderSecurityRoute(wrapper); expect(await screen.findByText(SECURITY_DESCRIPTION)).toBeInTheDocument(); - expect(screen.getByRole('button', { name: 'Start configuration' })).toBeInTheDocument(); + expect(screen.getByRole('button', { name: 'Configure' })).toBeInTheDocument(); }); it('blocks the security page on the guarded route when the user lacks the manage enterprise connections permission', async () => { @@ -608,7 +608,7 @@ describe('OrganizationProfile', () => { expect(fixtures.clerk.organization?.getEnterpriseConnections).not.toHaveBeenCalled(); expect(screen.queryByRole('heading', { name: 'Security' })).not.toBeInTheDocument(); expect(screen.queryByText(SECURITY_DESCRIPTION)).not.toBeInTheDocument(); - expect(screen.queryByRole('button', { name: 'Start configuration' })).not.toBeInTheDocument(); + expect(screen.queryByRole('button', { name: 'Configure' })).not.toBeInTheDocument(); }); }); diff --git a/packages/ui/src/components/OrganizationProfile/__tests__/OrganizationSecurityPage.test.tsx b/packages/ui/src/components/OrganizationProfile/__tests__/OrganizationSecurityPage.test.tsx index f0f815460e9..ffa51a203a0 100644 --- a/packages/ui/src/components/OrganizationProfile/__tests__/OrganizationSecurityPage.test.tsx +++ b/packages/ui/src/components/OrganizationProfile/__tests__/OrganizationSecurityPage.test.tsx @@ -1,4 +1,5 @@ import { ClerkAPIResponseError } from '@clerk/shared/error'; +import { within } from '@testing-library/react'; import { describe, expect, it, vi } from 'vitest'; import { bindCreateFixtures } from '@/test/create-fixtures'; @@ -47,12 +48,37 @@ const configuredConnection = (overrides: Record = {}) => ...overrides, }) as any; +const section = (id: 'sso' | 'directorySync') => + within(document.querySelector(`.cl-profileSection__${id}`) as HTMLElement); + +const findMenuButtons = (id: 'sso' | 'directorySync') => + waitFor(() => { + const buttons = section(id).getAllByRole('button', { name: /open menu/i }); + expect(buttons.length).toBeGreaterThan(0); + return buttons; + }); + +const openConnectionMenu = async (userEvent: ReturnType['userEvent'], index = 0) => { + const buttons = await findMenuButtons('sso'); + await userEvent.click(buttons[index]); +}; + +const openConnectionPage = async (userEvent: ReturnType['userEvent'], index = 0) => { + await openConnectionMenu(userEvent, index); + await userEvent.click(await screen.findByRole('menuitem', { name: 'Edit' })); +}; + +const openDirectorySyncMenu = async (userEvent: ReturnType['userEvent']) => { + const [button] = await findMenuButtons('directorySync'); + await userEvent.click(button); +}; + const renderPage = (wrapper: React.ComponentType<{ children?: React.ReactNode }>) => render(, { wrapper }); describe('OrganizationSecurityPage', () => { describe('overview states', () => { - it('renders the unconfigured state with a Start configuration action', async () => { + it('renders the unconfigured state with a Configure action', async () => { const { wrapper, fixtures } = await createFixtures(withSecurityPageFixtures); fixtures.clerk.organization?.getEnterpriseConnections.mockResolvedValue([]); @@ -60,19 +86,19 @@ describe('OrganizationSecurityPage', () => { renderPage(wrapper); // The "Security" header now also renders during the loading placeholder, so - // wait on the settled badge before asserting the page chrome and content. - expect(await screen.findByText('Unconfigured')).toBeInTheDocument(); + // wait on the settled action before asserting the page chrome and content. + expect(await screen.findByRole('button', { name: 'Configure' })).toBeInTheDocument(); expect(screen.getByRole('heading', { name: 'Security' })).toBeInTheDocument(); expect(screen.getByText('SSO')).toBeInTheDocument(); expect(screen.getByText(DESCRIPTION_LINE_1)).toBeInTheDocument(); - expect(screen.getByRole('button', { name: 'Start configuration' })).toBeInTheDocument(); + expect(screen.queryByText('Unconfigured')).not.toBeInTheDocument(); expect(screen.queryByRole('checkbox')).not.toBeInTheDocument(); expect(screen.queryByRole('button', { name: /open menu/i })).not.toBeInTheDocument(); expect(screen.queryByText(/select your identity provider/i)).not.toBeInTheDocument(); }); - it('renders the in-progress state as a clickable row', async () => { + it('renders the in-progress state as a row with a menu', async () => { const { wrapper, fixtures } = await createFixtures(withSecurityPageFixtures); // A connection without SAML configuration is mid-setup. @@ -91,8 +117,8 @@ describe('OrganizationSecurityPage', () => { expect(screen.queryByText(/you have started a configuration/i)).not.toBeInTheDocument(); expect(screen.queryByRole('checkbox')).not.toBeInTheDocument(); - expect(screen.getByRole('button', { name: /clerk\.com/ })).toBeInTheDocument(); - expect(screen.queryByRole('button', { name: /open menu/i })).not.toBeInTheDocument(); + expect(screen.queryByRole('button', { name: /clerk\.com/ })).not.toBeInTheDocument(); + expect(screen.getByRole('button', { name: /open menu/i })).toBeInTheDocument(); }); it('renders the active state as a condensed overview with the domains', async () => { @@ -108,19 +134,21 @@ describe('OrganizationSecurityPage', () => { expect(await screen.findByText('Active')).toBeInTheDocument(); expect(screen.getByText(DESCRIPTION_LINE_1)).toBeInTheDocument(); + expect(screen.getByLabelText('clerk.com icon')).toBeInTheDocument(); + expect(screen.queryByText('C')).not.toBeInTheDocument(); expect(screen.queryByRole('checkbox')).not.toBeInTheDocument(); expect(screen.queryByText(/^Domains:?$/)).not.toBeInTheDocument(); expect(screen.getAllByText('clerk.com').length).toBeGreaterThan(0); - expect(screen.getByRole('button', { name: /clerk\.com/ })).toBeInTheDocument(); - expect(screen.queryByRole('button', { name: /open menu/i })).not.toBeInTheDocument(); - expect(screen.queryByRole('button', { name: 'Start configuration' })).not.toBeInTheDocument(); + expect(screen.queryByRole('button', { name: /clerk\.com/ })).not.toBeInTheDocument(); + expect(screen.getByRole('button', { name: /open menu/i })).toBeInTheDocument(); + expect(screen.queryByRole('button', { name: 'Configure' })).not.toBeInTheDocument(); expect(screen.queryByRole('button', { name: 'Continue configuration' })).not.toBeInTheDocument(); }); - it('renders the inactive state with a chip per domain', async () => { + it('renders the inactive state with every domain in the caption', async () => { const { wrapper, fixtures } = await createFixtures(withSecurityPageFixtures); fixtures.clerk.organization?.getEnterpriseConnections.mockResolvedValue([ @@ -136,11 +164,9 @@ describe('OrganizationSecurityPage', () => { expect(await screen.findByText('Inactive')).toBeInTheDocument(); expect(screen.queryByRole('checkbox')).not.toBeInTheDocument(); - expect(screen.queryByRole('button', { name: /open menu/i })).not.toBeInTheDocument(); + expect(screen.getByRole('button', { name: /open menu/i })).toBeInTheDocument(); - for (const domain of ['github.com', 'gmail.com', 'maps.com', 'another.com']) { - expect(screen.getByText(domain)).toBeInTheDocument(); - } + expect(screen.getByText('github.com, gmail.com, maps.com, another.com')).toBeInTheDocument(); }); it('renders the full value for long domains', async () => { @@ -205,7 +231,7 @@ describe('OrganizationSecurityPage', () => { }); describe('view switching', () => { - it('opens the wizard at the first step when Start configuration is clicked', async () => { + it('opens the wizard at the first step when Configure is clicked', async () => { const { wrapper, fixtures } = await createFixtures(withSecurityPageFixtures); fixtures.clerk.organization?.getEnterpriseConnections.mockResolvedValue([]); @@ -213,43 +239,14 @@ describe('OrganizationSecurityPage', () => { const { userEvent } = renderPage(wrapper); - await userEvent.click(await screen.findByRole('button', { name: 'Start configuration' })); + await userEvent.click(await screen.findByRole('button', { name: 'Configure' })); // Start forces the first step. The fixture domain is already verified, so // without the forced entry the wizard would skip to select-provider — // proving Start threads `forceInitialStep`. expect(await screen.findByRole('heading', { name: /add SSO domains/i })).toBeInTheDocument(); expect(screen.queryByText(/select your identity provider/i)).not.toBeInTheDocument(); - expect(screen.queryByRole('button', { name: 'Start configuration' })).not.toBeInTheDocument(); - }); - - it("resumes the wizard at the reachable step from the connection page's Continue setup", async () => { - const { wrapper, fixtures } = await createFixtures(withSecurityPageFixtures); - - // A connection without SAML configuration is mid-setup (in_progress). - fixtures.clerk.organization?.getEnterpriseConnections.mockResolvedValue([ - configuredConnection({ samlConnection: null }), - ]); - fixtures.clerk.organization?.getEnterpriseConnectionTestRuns.mockResolvedValue({ - data: [], - total_count: 0, - } as any); - fixtures.clerk.organization?.getDomains.mockResolvedValue({ data: [verifiedDomain], total_count: 1 } as any); - - const { userEvent } = renderPage(wrapper); - - await userEvent.click(await screen.findByRole('button', { name: /clerk\.com/ })); - await userEvent.click(await screen.findByRole('button', { name: 'Continue setup' })); - - // The connection page forces no step, so the wizard resumes at the furthest- - // reachable step for this connection (configure, since a provider connection - // exists and the domain is verified) rather than the forced first step. - // Resuming into `configure` (direction 0) falls through to its furthest- - // reachable sub-step: a provider already exists, so it lands on - // `configure-provider` rather than re-showing `select-provider`. - expect(await screen.findByRole('heading', { name: /configure okta workforce/i })).toBeInTheDocument(); - expect(screen.queryByRole('heading', { name: /select your identity provider/i })).not.toBeInTheDocument(); - expect(screen.queryByRole('heading', { name: /add SSO domains/i })).not.toBeInTheDocument(); + expect(screen.queryByRole('button', { name: 'Configure' })).not.toBeInTheDocument(); }); }); @@ -263,44 +260,104 @@ describe('OrganizationSecurityPage', () => { const { userEvent } = renderPage(wrapper); // Enter the wizard from the overview. - await userEvent.click(await screen.findByRole('button', { name: 'Start configuration' })); + await userEvent.click(await screen.findByRole('button', { name: 'Configure' })); const backControl = await screen.findByRole('button', { name: 'Security' }); expect(backControl).toBeInTheDocument(); // The back control exits to the overview (the Start action returns). await userEvent.click(backControl); - expect(await screen.findByRole('button', { name: 'Start configuration' })).toBeInTheDocument(); + expect(await screen.findByRole('button', { name: 'Configure' })).toBeInTheDocument(); expect(screen.queryByRole('heading', { name: /add SSO domains/i })).not.toBeInTheDocument(); }); + }); - it('returns to the connection page when the wizard was opened from it', async () => { - const { wrapper, fixtures } = await createFixtures(withSecurityPageFixtures); - - fixtures.clerk.organization?.getEnterpriseConnections.mockResolvedValue([ - configuredConnection({ samlConnection: null }), - ]); + describe('connection row menu', () => { + const withConnection = ( + fixtures: any, + connection: any, + testRuns: unknown[] = [{ id: 'run_1', status: 'success' }], + ) => { + fixtures.clerk.organization?.getEnterpriseConnections.mockResolvedValue([connection]); fixtures.clerk.organization?.getEnterpriseConnectionTestRuns.mockResolvedValue({ - data: [], - total_count: 0, + data: testRuns, + total_count: testRuns.length, } as any); fixtures.clerk.organization?.getDomains.mockResolvedValue({ data: [verifiedDomain], total_count: 1 } as any); + }; + + it('lists Edit, Deactivate, and Remove for an active connection', async () => { + const { wrapper, fixtures } = await createFixtures(withSecurityPageFixtures); + withConnection(fixtures, configuredConnection({ active: true })); + + const { userEvent } = renderPage(wrapper); + + await openConnectionMenu(userEvent); + + expect(await screen.findByRole('menuitem', { name: 'Edit' })).toBeInTheDocument(); + expect(screen.getByRole('menuitem', { name: 'Deactivate' })).toBeInTheDocument(); + expect(screen.getByRole('menuitem', { name: 'Remove' })).toBeInTheDocument(); + expect(screen.queryByRole('menuitem', { name: 'Activate' })).not.toBeInTheDocument(); + expect(screen.queryByRole('menuitem', { name: 'Continue configuration' })).not.toBeInTheDocument(); + }); + + it('activates an inactive connection from the menu', async () => { + const { wrapper, fixtures } = await createFixtures(withSecurityPageFixtures); + withConnection(fixtures, configuredConnection({ active: false })); + fixtures.clerk.organization?.updateEnterpriseConnection.mockResolvedValue({} as any); const { userEvent } = renderPage(wrapper); - await userEvent.click(await screen.findByRole('button', { name: /clerk\.com/ })); - await userEvent.click(await screen.findByRole('button', { name: 'Continue setup' })); + await openConnectionMenu(userEvent); + expect(screen.queryByRole('menuitem', { name: 'Deactivate' })).not.toBeInTheDocument(); + await userEvent.click(await screen.findByRole('menuitem', { name: 'Activate' })); + + await waitFor(() => + expect(fixtures.clerk.organization?.updateEnterpriseConnection).toHaveBeenCalledWith( + 'ent_1', + expect.objectContaining({ active: true }), + ), + ); + }); + + it('resumes the wizard from Continue configuration on an in-progress connection', async () => { + const { wrapper, fixtures } = await createFixtures(withSecurityPageFixtures); + withConnection(fixtures, configuredConnection({ samlConnection: null }), []); + + const { userEvent } = renderPage(wrapper); + + await openConnectionMenu(userEvent); + expect(screen.queryByRole('menuitem', { name: 'Activate' })).not.toBeInTheDocument(); + expect(screen.queryByRole('menuitem', { name: 'Deactivate' })).not.toBeInTheDocument(); + await userEvent.click(await screen.findByRole('menuitem', { name: 'Continue configuration' })); + expect(await screen.findByRole('heading', { name: /configure okta workforce/i })).toBeInTheDocument(); + }); - await userEvent.click(await screen.findByRole('button', { name: 'Security' })); + it('removes a connection through the type-to-confirm dialog', async () => { + const { wrapper, fixtures } = await createFixtures(withSecurityPageFixtures); + withConnection(fixtures, configuredConnection({ active: true })); + fixtures.clerk.organization?.deleteEnterpriseConnection.mockResolvedValue({} as any); - expect(await screen.findByText('Danger zone')).toBeInTheDocument(); - expect(screen.queryByText(DESCRIPTION_LINE_1)).not.toBeInTheDocument(); + const { userEvent } = renderPage(wrapper); + + await openConnectionMenu(userEvent); + await userEvent.click(await screen.findByRole('menuitem', { name: 'Remove' })); + + const dialog = within(await screen.findByRole('dialog')); + await userEvent.type(dialog.getByRole('textbox'), 'Org1'); + fixtures.clerk.organization?.getEnterpriseConnections.mockResolvedValue([]); + await userEvent.click(dialog.getByRole('button', { name: /remove/i })); + + await waitFor(() => + expect(fixtures.clerk.organization?.deleteEnterpriseConnection).toHaveBeenCalledWith('ent_1'), + ); + expect(await screen.findByRole('button', { name: 'Configure' })).toBeInTheDocument(); }); }); describe('connection page', () => { - it('opens the connection page for the clicked row', async () => { + it('opens the connection page from the row menu Edit action', async () => { const { wrapper, fixtures } = await createFixtures(withSecurityPageFixtures); fixtures.clerk.organization?.getEnterpriseConnections.mockResolvedValue([configuredConnection({ active: true })]); @@ -311,7 +368,7 @@ describe('OrganizationSecurityPage', () => { const { userEvent } = renderPage(wrapper); - await userEvent.click(await screen.findByRole('button', { name: /clerk\.com/ })); + await openConnectionPage(userEvent); expect(await screen.findByRole('heading', { name: 'clerk.com' })).toBeInTheDocument(); expect(screen.getAllByText('Okta Workforce').length).toBeGreaterThan(0); @@ -330,7 +387,7 @@ describe('OrganizationSecurityPage', () => { const { userEvent } = renderPage(wrapper); - await userEvent.click(await screen.findByRole('button', { name: /clerk\.com/ })); + await openConnectionPage(userEvent); await userEvent.click(await screen.findByRole('button', { name: 'Security' })); expect(await screen.findByText(DESCRIPTION_LINE_1)).toBeInTheDocument(); @@ -353,11 +410,11 @@ describe('OrganizationSecurityPage', () => { const { userEvent } = renderPage(wrapper); - await userEvent.click(await screen.findByRole('button', { name: /clerk\.com/ })); + await openConnectionPage(userEvent); await userEvent.click(await screen.findByRole('checkbox', { name: /Sync user attributes/ })); await userEvent.click(screen.getByRole('button', { name: 'Save' })); - expect(await screen.findByRole('button', { name: 'Start configuration' })).toBeInTheDocument(); + expect(await screen.findByRole('button', { name: 'Configure' })).toBeInTheDocument(); expect(screen.queryByText('Identity provider')).not.toBeInTheDocument(); }); }); @@ -406,13 +463,13 @@ describe('OrganizationSecurityPage', () => { expect(screen.queryByText('Unconfigured')).not.toBeInTheDocument(); }); - it('opens the connection page of the clicked row', async () => { + it('opens the connection page of the row whose menu was used', async () => { const { wrapper, fixtures } = await createFixtures(withSecurityPageFixtures); withTwoConnections(fixtures); const { userEvent } = renderPage(wrapper); - await userEvent.click(await screen.findByRole('button', { name: /second\.com/ })); + await openConnectionPage(userEvent, 1); expect(await screen.findByRole('heading', { name: 'second.com' })).toBeInTheDocument(); expect(screen.queryByRole('heading', { name: 'first.com' })).not.toBeInTheDocument(); @@ -471,8 +528,7 @@ describe('OrganizationSecurityPage', () => { renderPage(wrapper); - expect(await screen.findByRole('button', { name: /clerk\.com/ })).toBeInTheDocument(); - expect(screen.queryByRole('button', { name: /open menu/i })).not.toBeInTheDocument(); + expect(await screen.findByText('Active')).toBeInTheDocument(); expect(screen.queryByText('Directory Sync')).not.toBeInTheDocument(); expect(fixtures.clerk.organization?.getDirectorySync).not.toHaveBeenCalled(); }); @@ -486,10 +542,14 @@ describe('OrganizationSecurityPage', () => { renderPage(wrapper); - const startButton = await screen.findByRole('button', { name: 'Start configuration' }); - expect(startButton).toBeEnabled(); - expect(screen.queryByText('SSO Required')).not.toBeInTheDocument(); - expect(screen.queryByRole('button', { name: /open menu/i })).not.toBeInTheDocument(); + const configureButton = await screen.findByRole('button', { name: 'Configure' }); + expect(configureButton).toBeEnabled(); + expect( + screen.getByText('Keep organization members synced with your identity provider. Requires an SSO connection.'), + ).toBeInTheDocument(); + expect(screen.queryByText('Unconfigured')).not.toBeInTheDocument(); + expect(screen.queryByText('SSO required')).not.toBeInTheDocument(); + expect(section('directorySync').queryByRole('button', { name: /open menu/i })).not.toBeInTheDocument(); }); it('surfaces a load error when the directory request fails for any other reason', async () => { @@ -505,8 +565,8 @@ describe('OrganizationSecurityPage', () => { renderPage(wrapper); expect(await screen.findByText('Could not load Directory Sync')).toBeInTheDocument(); - expect(screen.queryByRole('button', { name: 'Start configuration' })).not.toBeInTheDocument(); - expect(screen.queryByRole('button', { name: /open menu/i })).not.toBeInTheDocument(); + expect(screen.queryByRole('button', { name: 'Configure' })).not.toBeInTheDocument(); + expect(section('directorySync').queryByRole('button', { name: /open menu/i })).not.toBeInTheDocument(); }); it('disables setup and flags SSO as required when no connection exists', async () => { @@ -516,11 +576,10 @@ describe('OrganizationSecurityPage', () => { renderPage(wrapper); - expect(await screen.findByText('SSO Required')).toBeInTheDocument(); - const startButtons = screen.getAllByRole('button', { name: 'Start configuration' }); - expect(startButtons).toHaveLength(2); - expect(startButtons[0]).toBeEnabled(); - expect(startButtons[1]).toBeDisabled(); + expect(await screen.findByText('SSO required')).toBeInTheDocument(); + const [ssoConfigureButton, directorySyncConfigureButton] = screen.getAllByRole('button', { name: 'Configure' }); + expect(ssoConfigureButton).toBeEnabled(); + expect(directorySyncConfigureButton).toBeDisabled(); expect(fixtures.clerk.organization?.getDirectorySync).not.toHaveBeenCalled(); }); @@ -538,7 +597,7 @@ describe('OrganizationSecurityPage', () => { // Google used to be sent to the Clerk Dashboard here, which is the Clerk // customer's account rather than the admin's, so setup dead-ended. - expect(await screen.findByRole('button', { name: 'Start configuration' })).toBeEnabled(); + expect(await screen.findByRole('button', { name: 'Configure' })).toBeEnabled(); expect( screen.queryByText('Google Workspace connections are not configurable via self-serve'), ).not.toBeInTheDocument(); @@ -551,7 +610,7 @@ describe('OrganizationSecurityPage', () => { const { userEvent } = renderPage(wrapper); - await userEvent.click(await screen.findByRole('button', { name: /open menu/i })); + await openDirectorySyncMenu(userEvent); expect(screen.getByRole('menuitem', { name: 'Edit' })).toBeInTheDocument(); expect(screen.getByRole('menuitem', { name: 'Deactivate' })).toBeInTheDocument(); @@ -571,12 +630,12 @@ describe('OrganizationSecurityPage', () => { const { userEvent } = renderPage(wrapper); - await userEvent.click(await screen.findByRole('button', { name: /open menu/i })); + await openDirectorySyncMenu(userEvent); await userEvent.click(screen.getByRole('menuitem', { name: 'Deactivate' })); expect(activeDirectory.update).toHaveBeenCalledWith({ enabled: false }); - await userEvent.click(screen.getByRole('button', { name: /open menu/i })); + await openDirectorySyncMenu(userEvent); await waitFor(() => expect(screen.getByRole('menuitem', { name: 'Activate' })).toBeInTheDocument()); }); @@ -589,7 +648,7 @@ describe('OrganizationSecurityPage', () => { const { userEvent } = renderPage(wrapper); - await userEvent.click(await screen.findByRole('button', { name: /open menu/i })); + await openDirectorySyncMenu(userEvent); await userEvent.click(screen.getByRole('menuitem', { name: 'Remove' })); expect(await screen.findByRole('heading', { name: 'Remove Directory Sync' })).toBeInTheDocument(); @@ -600,7 +659,7 @@ describe('OrganizationSecurityPage', () => { await userEvent.click(confirmButton); expect(activeDirectory.delete).toHaveBeenCalledWith(); - await waitFor(() => expect(screen.getByRole('button', { name: 'Start configuration' })).toBeInTheDocument()); + await waitFor(() => expect(screen.getByRole('button', { name: 'Configure' })).toBeInTheDocument()); // Typing the confirmation and swapping the section back has hit the 5s default on CI. }, 15_000); @@ -611,7 +670,7 @@ describe('OrganizationSecurityPage', () => { const { userEvent } = renderPage(wrapper); - await userEvent.click(await screen.findByRole('button', { name: /open menu/i })); + await openDirectorySyncMenu(userEvent); await userEvent.click(screen.getByRole('menuitem', { name: 'Edit' })); await waitFor(() => expect(screen.queryByRole('button', { name: /open menu/i })).not.toBeInTheDocument()); diff --git a/packages/ui/src/components/OrganizationProfile/__tests__/SSOBypassAllowlist.test.tsx b/packages/ui/src/components/OrganizationProfile/__tests__/SSOBypassAllowlist.test.tsx index cd0e9e1fcc4..639992a9c6a 100644 --- a/packages/ui/src/components/OrganizationProfile/__tests__/SSOBypassAllowlist.test.tsx +++ b/packages/ui/src/components/OrganizationProfile/__tests__/SSOBypassAllowlist.test.tsx @@ -1,3 +1,4 @@ +import { within } from '@testing-library/react'; import { beforeEach, describe, expect, it } from 'vitest'; import { clearFetchCache } from '@/hooks/useFetch'; @@ -109,7 +110,7 @@ describe('SSO bypass allowlist', () => { renderPage(wrapper); - expect(await screen.findByRole('button', { name: 'Start configuration' })).toBeInTheDocument(); + expect(await screen.findByRole('button', { name: 'Configure' })).toBeInTheDocument(); expect(screen.queryByText('SSO bypass')).not.toBeInTheDocument(); }); @@ -152,7 +153,11 @@ describe('SSO bypass allowlist', () => { expect(await screen.findByText('1 member')).toBeInTheDocument(); - await userEvent.click(screen.getByRole('button', { name: /open menu/i })); + await userEvent.click( + within(document.querySelector('.cl-profileSection__ssoBypass') as HTMLElement).getByRole('button', { + name: /open menu/i, + }), + ); await userEvent.click(await screen.findByRole('menuitem', { name: 'Manage' })); expect(await screen.findByRole('heading', { name: 'SSO bypass' })).toBeInTheDocument(); @@ -187,7 +192,11 @@ describe('SSO bypass allowlist', () => { const userEventOpen = async (userEvent: ReturnType['userEvent']) => { await screen.findByText('SSO bypass'); - await userEvent.click(screen.getByRole('button', { name: /open menu/i })); + await userEvent.click( + within(document.querySelector('.cl-profileSection__ssoBypass') as HTMLElement).getByRole('button', { + name: /open menu/i, + }), + ); await userEvent.click(await screen.findByRole('menuitem', { name: 'Manage' })); await screen.findByRole('heading', { name: 'SSO bypass' }); }; @@ -474,9 +483,13 @@ describe('SSO bypass allowlist', () => { expect(screen.getByText(SSO_DESCRIPTION)).toBeInTheDocument(); expect(screen.getByText('Active')).toBeInTheDocument(); - expect(screen.queryByRole('button', { name: /clerk\.com/ })).not.toBeInTheDocument(); + expect( + within(document.querySelector('.cl-profileSection__sso') as HTMLElement).queryByRole('button', { + name: /open menu/i, + }), + ).not.toBeInTheDocument(); expect(screen.queryByRole('button', { name: 'Add connection' })).not.toBeInTheDocument(); - expect(screen.queryByRole('button', { name: 'Start configuration' })).not.toBeInTheDocument(); + expect(screen.queryByRole('button', { name: 'Configure' })).not.toBeInTheDocument(); expect(fixtures.clerk.organization?.getEnterpriseConnectionTestRuns).not.toHaveBeenCalled(); }); diff --git a/packages/ui/src/components/OrganizationProfile/enterpriseConnectionStatusBadges.ts b/packages/ui/src/components/OrganizationProfile/enterpriseConnectionStatusBadges.ts index 73b43cad2fa..aa17c4c0b6c 100644 --- a/packages/ui/src/components/OrganizationProfile/enterpriseConnectionStatusBadges.ts +++ b/packages/ui/src/components/OrganizationProfile/enterpriseConnectionStatusBadges.ts @@ -4,7 +4,7 @@ import type { OrganizationEnterpriseConnectionStatus } from '../ConfigureSSO/dom export const STATUS_BADGES: Record< OrganizationEnterpriseConnectionStatus, - { id: string; colorScheme?: 'primary' | 'danger' | 'warning' | 'success'; label: LocalizationKey } + { id: string; colorScheme: 'primary'; label: LocalizationKey } > = { unconfigured: { id: 'unconfigured', @@ -13,17 +13,17 @@ export const STATUS_BADGES: Record< }, in_progress: { id: 'inProgress', - colorScheme: 'warning', + colorScheme: 'primary', label: localizationKeys('organizationProfile.securityPage.ssoSection.badge__inProgress'), }, active: { id: 'active', - colorScheme: 'success', + colorScheme: 'primary', label: localizationKeys('organizationProfile.securityPage.ssoSection.badge__active'), }, inactive: { id: 'inactive', - colorScheme: 'danger', + colorScheme: 'primary', label: localizationKeys('organizationProfile.securityPage.ssoSection.badge__inactive'), }, }; From f47e011e0f20c13cc7fd426bcd620114b64f84f1 Mon Sep 17 00:00:00 2001 From: Jim Kalafut Date: Fri, 25 Sep 2026 10:55:12 -0700 Subject: [PATCH 2/3] Fix CI checks --- .changeset/security-page-redesign.md | 2 +- integration/tests/composed-components.test.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.changeset/security-page-redesign.md b/.changeset/security-page-redesign.md index 85b0e688870..250fa89f9e1 100644 --- a/.changeset/security-page-redesign.md +++ b/.changeset/security-page-redesign.md @@ -4,6 +4,6 @@ '@clerk/ui': minor --- -Update the SSO and Directory Sync sections of the `` Security page to the latest designs. Both sections now start with a "Configure" button, and SSO connection rows show the identity provider's logo and an actions menu (Edit, Continue configuration, Activate/Deactivate, Remove). These actions have been removed from the SSO connection page, and status badges are no longer color-coded. +Update the SSO and Directory Sync sections of the `` Security page to the latest designs. Both sections now show a "Configure" button until something is set up (SSO then shows "Add connection"), and SSO connection rows show the identity provider's logo and an actions menu (Edit, Continue configuration, Activate/Deactivate, Remove). These actions have been removed from the SSO connection page, and status badges are no longer color-coded. The SSO button uses the new `ssoSection.primaryButton__configure` localization key; `ssoSection.primaryButton__startConfiguration` is deprecated and no longer used. In `directorySyncSection`, `primaryButton__startConfiguration` is renamed to `primaryButton__configure` and `badge__unconfigured` is removed. diff --git a/integration/tests/composed-components.test.ts b/integration/tests/composed-components.test.ts index 439a79d344f..515993a8eb5 100644 --- a/integration/tests/composed-components.test.ts +++ b/integration/tests/composed-components.test.ts @@ -463,6 +463,6 @@ test.describe('composed OrganizationProfile exports @generic', () => { // the composed counterpart to the security tab (there are no composable sub-sections here). await expect(u.page.getByRole('heading', { name: /^security$/i })).toBeVisible(); await expect(u.page.getByText(/^SSO$/)).toBeVisible(); - await expect(u.page.getByRole('button', { name: /start configuration/i })).toBeVisible(); + await expect(u.page.locator('.cl-profileSection__sso').getByRole('button', { name: /^configure$/i })).toBeVisible(); }); }); From 99d869c01a0eb9d801c85eb7bf7b10dd232860ff Mon Sep 17 00:00:00 2001 From: Jim Kalafut Date: Fri, 25 Sep 2026 13:41:47 -0700 Subject: [PATCH 3/3] refactor(ui): use ProviderIcon's mask list for the Okta logo Add `okta` to `SUPPORTS_MASK_IMAGE` and drop the separate `MONOCHROMATIC_PROVIDER_ICONS` list. `EnterpriseConnectionIcon` and the SSO wizard's provider cards now render through `ProviderIcon` instead of their own mask styles. --- .changeset/security-page-redesign.md | 2 +- packages/ui/src/common/ProviderIcon.tsx | 2 +- .../ConfigureSSO/domain/providers.ts | 2 -- .../ConfigureSSO/steps/SelectProviderStep.tsx | 34 +++++-------------- .../EnterpriseConnectionIcon.tsx | 15 +------- 5 files changed, 12 insertions(+), 43 deletions(-) diff --git a/.changeset/security-page-redesign.md b/.changeset/security-page-redesign.md index 250fa89f9e1..3beac907ce8 100644 --- a/.changeset/security-page-redesign.md +++ b/.changeset/security-page-redesign.md @@ -4,6 +4,6 @@ '@clerk/ui': minor --- -Update the SSO and Directory Sync sections of the `` Security page to the latest designs. Both sections now show a "Configure" button until something is set up (SSO then shows "Add connection"), and SSO connection rows show the identity provider's logo and an actions menu (Edit, Continue configuration, Activate/Deactivate, Remove). These actions have been removed from the SSO connection page, and status badges are no longer color-coded. +Update the SSO and Directory Sync sections of the `` Security page to the latest designs. Both sections now show a "Configure" button until something is set up (SSO then shows "Add connection"), and SSO connection rows show the identity provider's logo and an actions menu (Edit, Continue configuration, Activate/Deactivate, Remove). These actions have been removed from the SSO connection page, and status badges are no longer color-coded. Okta logos now follow the theme's foreground color, so they stay visible in dark mode, including on the enterprise connection chooser and in ``. The SSO button uses the new `ssoSection.primaryButton__configure` localization key; `ssoSection.primaryButton__startConfiguration` is deprecated and no longer used. In `directorySyncSection`, `primaryButton__startConfiguration` is renamed to `primaryButton__configure` and `badge__unconfigured` is removed. diff --git a/packages/ui/src/common/ProviderIcon.tsx b/packages/ui/src/common/ProviderIcon.tsx index 36c29883435..05f77e0d05f 100644 --- a/packages/ui/src/common/ProviderIcon.tsx +++ b/packages/ui/src/common/ProviderIcon.tsx @@ -7,7 +7,7 @@ import { ProviderInitialIcon } from './ProviderInitialIcon'; type ProviderId = OAuthProvider | Web3Provider | PhoneCodeChannel; -export const SUPPORTS_MASK_IMAGE = ['agentid', 'apple', 'github', 'okx_wallet', 'vercel', 'x'] as const; +export const SUPPORTS_MASK_IMAGE = ['agentid', 'apple', 'github', 'okta', 'okx_wallet', 'vercel', 'x'] as const; export const getEnterpriseProviderIconId = (provider: string) => provider.replace(/(oauth_|saml_)/, '').trim() as OAuthProvider; diff --git a/packages/ui/src/components/ConfigureSSO/domain/providers.ts b/packages/ui/src/components/ConfigureSSO/domain/providers.ts index c1e0f09e726..1619b2a3008 100644 --- a/packages/ui/src/components/ConfigureSSO/domain/providers.ts +++ b/packages/ui/src/components/ConfigureSSO/domain/providers.ts @@ -52,8 +52,6 @@ export const PROVIDER_GROUPS: ReadonlyArray = [ }, ]; -export const MONOCHROMATIC_PROVIDER_ICONS: ReadonlySet = new Set(['okta']); - export const providerLabel = (provider: ProviderType): LocalizationKey | undefined => PROVIDER_GROUPS.flatMap(group => group.options).find(option => option.id === provider)?.label; diff --git a/packages/ui/src/components/ConfigureSSO/steps/SelectProviderStep.tsx b/packages/ui/src/components/ConfigureSSO/steps/SelectProviderStep.tsx index d33c6d6c626..48a61878dfb 100644 --- a/packages/ui/src/components/ConfigureSSO/steps/SelectProviderStep.tsx +++ b/packages/ui/src/components/ConfigureSSO/steps/SelectProviderStep.tsx @@ -1,6 +1,8 @@ import { iconImageUrl } from '@clerk/shared/constants'; +import type { OAuthProvider } from '@clerk/shared/types'; import React from 'react'; +import { ProviderIcon } from '@/common'; import type { LocalizationKey } from '@/customizables'; import { Box, @@ -10,7 +12,6 @@ import { Grid, localizationKeys, RadioInput, - Span, Text, useLocalizations, } from '@/customizables'; @@ -21,7 +22,7 @@ import { getFieldError, getGlobalError, handleError } from '@/utils/errorHandler import { ChangeProviderDialog } from '../ChangeProviderDialog'; import { useConfigureSSO } from '../ConfigureSSOContext'; -import { MONOCHROMATIC_PROVIDER_ICONS, PROVIDER_GROUPS, providerLabel, toProviderCard } from '../domain/providers'; +import { PROVIDER_GROUPS, providerLabel, toProviderCard } from '../domain/providers'; import { Step } from '../elements/Step'; import { useWizard } from '../elements/Wizard'; import type { ProviderType } from '../types'; @@ -272,31 +273,14 @@ const ProviderCard = ({ name, value, iconId, label, checked, onChange }: Provide sx={common.visuallyHidden()} /> - { - const isMonochromatic = MONOCHROMATIC_PROVIDER_ICONS.has(iconId); - const baseSize = { width: theme.sizes.$8, height: theme.sizes.$8 }; - if (isMonochromatic) { - return { - ...baseSize, - backgroundColor: theme.colors.$colorForeground, - maskImage: `url(${iconImageUrl(iconId)})`, - maskSize: 'contain', - maskPosition: 'center', - maskRepeat: 'no-repeat', - }; - } - return { - ...baseSize, - backgroundImage: `url(${iconImageUrl(iconId)})`, - backgroundSize: 'contain', - backgroundPosition: 'center', - backgroundRepeat: 'no-repeat', - }; - }} /> { const iconId = providerIconId(toProviderCard(connection.provider as EnterpriseConnectionProviderType)); const iconUrl = iconId ? iconImageUrl(iconId) : connection.logoPublicUrl?.trim(); - const isMonochromatic = iconId !== undefined && MONOCHROMATIC_PROVIDER_ICONS.has(iconId); return ( ({ - backgroundImage: 'none', - backgroundColor: t.colors.$colorForeground, - maskImage: `url(${iconUrl})`, - maskSize: 'contain', - maskPosition: 'center', - maskRepeat: 'no-repeat', - }) - : { backgroundSize: 'contain' } - } /> ); };