diff --git a/.changeset/security-page-redesign.md b/.changeset/security-page-redesign.md new file mode 100644 index 00000000000..3beac907ce8 --- /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 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/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(); }); }); diff --git a/packages/localizations/src/ar-SA.ts b/packages/localizations/src/ar-SA.ts index 7ab7fe9f682..51eb8049416 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 2ca6811c35c..2d3047732f7 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 4b46d8928c5..97e0dea7866 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 18778b578c7..e4903dd4680 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 6a182d97bf4..415dfb5651c 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 2c136eeed54..be7ddf037c6 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 e6a3452295e..e9b3b4facda 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 a790bf6e48a..85211a28986 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 a81d77042e9..0467f20fb50 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 c8f21c414d8..e028cff9e6f 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 58523350769..abbcb744c3f 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 20fde8d7627..f13e61b1055 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 8a3e3b077c0..175e88c7ef6 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 9fbd1657c41..35a9eab3747 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 4642d64e309..5f03cd55126 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 c5394488e72..72e0ee3f716 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 acf81048405..c3b07cb926e 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 b53badd7457..31685940074 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 0feb281e01f..0c49ef326f3 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 eb8921f1811..3b2df157c4a 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 0e6b43d4eee..40c4423cc1c 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 2df3cf0f335..bd0aeb00fc0 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 8506ee752a1..bb8f7a58b70 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 2725cb0ec66..f53f4d6cff5 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 818aa2c99c8..826889a94b4 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 4a5a0fe7001..c2cdb2926ad 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 7134dfb7483..306bd58ce3c 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 24de87d4e9d..8b76029443a 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 108ba8014de..375c45efd4a 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 fda67db9c75..ed21fbaef48 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 58ee9d09a6d..9e42aac4b76 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 03c02cecc3d..ddd60976415 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 8896e27a07b..e2a1969b441 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 aa8adc2a60c..76d3adc7ea9 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 df49686106b..0d9ac6023a7 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 b6538ce7947..4440c052473 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 20d5a8a8107..b372cf79c68 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 216d06bd8f0..07d081dd992 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 857dd72424f..fc9169d88d2 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 1e36e637efa..cc7fbb83dfb 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 be7b87b178a..4277bb57a62 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 73272043e6e..8f8ee372d62 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 1256ecff435..957f053751c 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 5a002a7b01b..c98233dba9f 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 f1736ecb0e4..fe69dcdc525 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 73699280b51..e3a16b8ea27 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 1fae7626221..8c543c1e108 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 a3ac19925ce..2537e98bae0 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 54c411d38c2..a8db934fa49 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 cd015a831ff..588bd91a29f 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/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/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'), }, };