@workos-inc/widgets 1.8.2 → 1.9.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (113) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/dist/cjs/admin-portal-domain-verification.client.cjs.map +1 -1
  3. package/dist/cjs/admin-portal-sso-connection.client.cjs +4 -7
  4. package/dist/cjs/admin-portal-sso-connection.client.cjs.map +1 -1
  5. package/dist/cjs/api/api-provider.cjs.map +1 -1
  6. package/dist/cjs/api/api-provider.d.cts +1 -1
  7. package/dist/cjs/api/endpoint.cjs +741 -771
  8. package/dist/cjs/api/endpoint.cjs.map +1 -1
  9. package/dist/cjs/api/endpoint.d.cts +860 -813
  10. package/dist/cjs/directory-sync.client.cjs +156 -0
  11. package/dist/cjs/directory-sync.client.cjs.map +1 -0
  12. package/dist/cjs/directory-sync.client.d.cts +26 -0
  13. package/dist/cjs/experimental/api/fetch.cjs +327 -411
  14. package/dist/cjs/experimental/api/fetch.cjs.map +1 -1
  15. package/dist/cjs/experimental/api/fetch.d.cts +832 -798
  16. package/dist/cjs/experimental/api/react-query.cjs +747 -777
  17. package/dist/cjs/experimental/api/react-query.cjs.map +1 -1
  18. package/dist/cjs/experimental/api/react-query.d.cts +1378 -1263
  19. package/dist/cjs/experimental/api/swr.cjs +720 -742
  20. package/dist/cjs/experimental/api/swr.cjs.map +1 -1
  21. package/dist/cjs/experimental/api/swr.d.cts +1218 -1175
  22. package/dist/cjs/index.cjs +5 -0
  23. package/dist/cjs/index.cjs.map +1 -1
  24. package/dist/cjs/index.d.cts +2 -0
  25. package/dist/cjs/lib/add-mfa-dialog.cjs +18 -16
  26. package/dist/cjs/lib/add-mfa-dialog.cjs.map +1 -1
  27. package/dist/cjs/lib/admin-portal-sso-connection.cjs +0 -8
  28. package/dist/cjs/lib/admin-portal-sso-connection.cjs.map +1 -1
  29. package/dist/cjs/lib/admin-portal-sso-connection.d.cts +1 -2
  30. package/dist/cjs/lib/api-keys/api-keys-context.cjs +1 -1
  31. package/dist/cjs/lib/api-keys/api-keys-context.cjs.map +1 -1
  32. package/dist/cjs/lib/api-keys/api-keys-table.cjs +7 -5
  33. package/dist/cjs/lib/api-keys/api-keys-table.cjs.map +1 -1
  34. package/dist/cjs/lib/directory-sync.cjs +288 -0
  35. package/dist/cjs/lib/directory-sync.cjs.map +1 -0
  36. package/dist/cjs/lib/directory-sync.d.cts +72 -0
  37. package/dist/cjs/lib/identity-providers.cjs +57 -1
  38. package/dist/cjs/lib/identity-providers.cjs.map +1 -1
  39. package/dist/cjs/lib/identity-providers.d.cts +5 -3
  40. package/dist/cjs/lib/pipes.cjs +9 -9
  41. package/dist/cjs/lib/pipes.cjs.map +1 -1
  42. package/dist/cjs/lib/provider-icon.cjs.map +1 -1
  43. package/dist/cjs/lib/provider-icon.d.cts +2 -2
  44. package/dist/cjs/lib/reset-mfa-dialog.cjs +2 -1
  45. package/dist/cjs/lib/reset-mfa-dialog.cjs.map +1 -1
  46. package/dist/cjs/lib/use-permissions.cjs.map +1 -1
  47. package/dist/cjs/lib/use-permissions.d.cts +1 -1
  48. package/dist/cjs/lib/users-management-context.cjs +1 -1
  49. package/dist/cjs/lib/users-management-context.cjs.map +1 -1
  50. package/dist/cjs/lib/users-management.cjs +3 -3
  51. package/dist/cjs/lib/users-management.cjs.map +1 -1
  52. package/dist/cjs/lib/utils.cjs +9 -0
  53. package/dist/cjs/lib/utils.cjs.map +1 -1
  54. package/dist/cjs/lib/utils.d.cts +16 -2
  55. package/dist/cjs/workos-widgets.client.cjs +13 -1
  56. package/dist/cjs/workos-widgets.client.cjs.map +1 -1
  57. package/dist/esm/admin-portal-domain-verification.client.js +2 -2
  58. package/dist/esm/admin-portal-domain-verification.client.js.map +1 -1
  59. package/dist/esm/admin-portal-sso-connection.client.js +6 -9
  60. package/dist/esm/admin-portal-sso-connection.client.js.map +1 -1
  61. package/dist/esm/api/api-provider.d.ts +1 -1
  62. package/dist/esm/api/api-provider.js.map +1 -1
  63. package/dist/esm/api/endpoint.d.ts +860 -813
  64. package/dist/esm/api/endpoint.js +727 -751
  65. package/dist/esm/api/endpoint.js.map +1 -1
  66. package/dist/esm/directory-sync.client.d.ts +26 -0
  67. package/dist/esm/directory-sync.client.js +134 -0
  68. package/dist/esm/directory-sync.client.js.map +1 -0
  69. package/dist/esm/experimental/api/fetch.d.ts +832 -798
  70. package/dist/esm/experimental/api/fetch.js +319 -391
  71. package/dist/esm/experimental/api/fetch.js.map +1 -1
  72. package/dist/esm/experimental/api/react-query.d.ts +1378 -1263
  73. package/dist/esm/experimental/api/react-query.js +730 -757
  74. package/dist/esm/experimental/api/react-query.js.map +1 -1
  75. package/dist/esm/experimental/api/swr.d.ts +1218 -1175
  76. package/dist/esm/experimental/api/swr.js +706 -722
  77. package/dist/esm/experimental/api/swr.js.map +1 -1
  78. package/dist/esm/index.d.ts +2 -0
  79. package/dist/esm/index.js +6 -0
  80. package/dist/esm/index.js.map +1 -1
  81. package/dist/esm/lib/add-mfa-dialog.js +18 -16
  82. package/dist/esm/lib/add-mfa-dialog.js.map +1 -1
  83. package/dist/esm/lib/admin-portal-sso-connection.d.ts +1 -2
  84. package/dist/esm/lib/admin-portal-sso-connection.js +0 -8
  85. package/dist/esm/lib/admin-portal-sso-connection.js.map +1 -1
  86. package/dist/esm/lib/api-keys/api-keys-context.js +1 -1
  87. package/dist/esm/lib/api-keys/api-keys-context.js.map +1 -1
  88. package/dist/esm/lib/api-keys/api-keys-table.js +7 -5
  89. package/dist/esm/lib/api-keys/api-keys-table.js.map +1 -1
  90. package/dist/esm/lib/directory-sync.d.ts +72 -0
  91. package/dist/esm/lib/directory-sync.js +259 -0
  92. package/dist/esm/lib/directory-sync.js.map +1 -0
  93. package/dist/esm/lib/identity-providers.d.ts +5 -3
  94. package/dist/esm/lib/identity-providers.js +55 -1
  95. package/dist/esm/lib/identity-providers.js.map +1 -1
  96. package/dist/esm/lib/pipes.js +9 -10
  97. package/dist/esm/lib/pipes.js.map +1 -1
  98. package/dist/esm/lib/provider-icon.d.ts +2 -2
  99. package/dist/esm/lib/provider-icon.js.map +1 -1
  100. package/dist/esm/lib/reset-mfa-dialog.js +2 -1
  101. package/dist/esm/lib/reset-mfa-dialog.js.map +1 -1
  102. package/dist/esm/lib/use-permissions.d.ts +1 -1
  103. package/dist/esm/lib/use-permissions.js.map +1 -1
  104. package/dist/esm/lib/users-management-context.js +1 -1
  105. package/dist/esm/lib/users-management-context.js.map +1 -1
  106. package/dist/esm/lib/users-management.js +5 -4
  107. package/dist/esm/lib/users-management.js.map +1 -1
  108. package/dist/esm/lib/utils.d.ts +16 -2
  109. package/dist/esm/lib/utils.js +8 -0
  110. package/dist/esm/lib/utils.js.map +1 -1
  111. package/dist/esm/workos-widgets.client.js +13 -1
  112. package/dist/esm/workos-widgets.client.js.map +1 -1
  113. package/package.json +2 -2
@@ -24,6 +24,8 @@ __export(index_exports, {
24
24
  AdminPortalSsoConnectionLoading: () => import_admin_portal_sso_connection_client.AdminPortalSsoConnectionLoading,
25
25
  ApiKeys: () => import_api_keys_client.ApiKeys,
26
26
  ApiKeysLoading: () => import_api_keys_client.ApiKeysLoading,
27
+ DirectorySync: () => import_directory_sync_client.DirectorySync,
28
+ DirectorySyncLoading: () => import_directory_sync_client.DirectorySyncLoading,
27
29
  OrganizationSwitcher: () => import_organization_switcher_client.OrganizationSwitcher,
28
30
  OrganizationSwitcherLoading: () => import_organization_switcher_client.OrganizationSwitcherLoading,
29
31
  Pipes: () => import_pipes_client.Pipes,
@@ -50,6 +52,7 @@ var import_users_management_client = require("./users-management.client.js");
50
52
  var import_admin_portal_domain_verification_client = require("./admin-portal-domain-verification.client.js");
51
53
  var import_api_keys_client = require("./api-keys.client.js");
52
54
  var import_pipes_client = require("./pipes.client.js");
55
+ var import_directory_sync_client = require("./directory-sync.client.js");
53
56
  var import_intl_context = require("./lib/i18n/intl-context.js");
54
57
  // Annotate the CommonJS export names for ESM import in node:
55
58
  0 && (module.exports = {
@@ -59,6 +62,8 @@ var import_intl_context = require("./lib/i18n/intl-context.js");
59
62
  AdminPortalSsoConnectionLoading,
60
63
  ApiKeys,
61
64
  ApiKeysLoading,
65
+ DirectorySync,
66
+ DirectorySyncLoading,
62
67
  OrganizationSwitcher,
63
68
  OrganizationSwitcherLoading,
64
69
  Pipes,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/index.ts"],"sourcesContent":["export {\n WorkOsWidgets,\n type WorkOsWidgetsProps,\n} from \"./workos-widgets.client.js\";\nexport {\n OrganizationSwitcher,\n OrganizationSwitcherLoading,\n type OrganizationSwitcherProps,\n} from \"./organization-switcher.client.js\";\nexport {\n AdminPortalSsoConnection,\n AdminPortalSsoConnectionLoading,\n type AdminPortalSsoConnectionProps,\n} from \"./admin-portal-sso-connection.client.js\";\nexport {\n UserProfile,\n UserProfileLoading,\n type UserProfileProps,\n} from \"./user-profile.client.js\";\nexport {\n UserSecurity,\n UserSecurityLoading,\n type UserSecurityProps,\n} from \"./user-security.client.js\";\nexport {\n UserSessions,\n UserSessionsLoading,\n type UserSessionsProps,\n} from \"./user-sessions.client.js\";\nexport {\n UsersManagement,\n UsersManagementLoading,\n type UsersManagementProps,\n} from \"./users-management.client.js\";\nexport {\n AdminPortalDomainVerification,\n AdminPortalDomainVerificationLoading,\n type AdminPortalDomainVerificationProps,\n} from \"./admin-portal-domain-verification.client.js\";\nexport {\n ApiKeys,\n ApiKeysLoading,\n type ApiKeysProps,\n} from \"./api-keys.client.js\";\nexport { Pipes, PipesLoading, type PipesProps } from \"./pipes.client.js\";\nexport { IntlContext as internal_IntlContext } from \"./lib/i18n/intl-context.js\";\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mCAGO;AACP,0CAIO;AACP,gDAIO;AACP,iCAIO;AACP,kCAIO;AACP,kCAIO;AACP,qCAIO;AACP,qDAIO;AACP,6BAIO;AACP,0BAAqD;AACrD,0BAAoD;","names":[]}
1
+ {"version":3,"sources":["../../src/index.ts"],"sourcesContent":["export {\n WorkOsWidgets,\n type WorkOsWidgetsProps,\n} from \"./workos-widgets.client.js\";\nexport {\n OrganizationSwitcher,\n OrganizationSwitcherLoading,\n type OrganizationSwitcherProps,\n} from \"./organization-switcher.client.js\";\nexport {\n AdminPortalSsoConnection,\n AdminPortalSsoConnectionLoading,\n type AdminPortalSsoConnectionProps,\n} from \"./admin-portal-sso-connection.client.js\";\nexport {\n UserProfile,\n UserProfileLoading,\n type UserProfileProps,\n} from \"./user-profile.client.js\";\nexport {\n UserSecurity,\n UserSecurityLoading,\n type UserSecurityProps,\n} from \"./user-security.client.js\";\nexport {\n UserSessions,\n UserSessionsLoading,\n type UserSessionsProps,\n} from \"./user-sessions.client.js\";\nexport {\n UsersManagement,\n UsersManagementLoading,\n type UsersManagementProps,\n} from \"./users-management.client.js\";\nexport {\n AdminPortalDomainVerification,\n AdminPortalDomainVerificationLoading,\n type AdminPortalDomainVerificationProps,\n} from \"./admin-portal-domain-verification.client.js\";\nexport {\n ApiKeys,\n ApiKeysLoading,\n type ApiKeysProps,\n} from \"./api-keys.client.js\";\nexport { Pipes, PipesLoading, type PipesProps } from \"./pipes.client.js\";\nexport {\n DirectorySync,\n DirectorySyncLoading,\n type DirectorySyncProps,\n} from \"./directory-sync.client.js\";\nexport { IntlContext as internal_IntlContext } from \"./lib/i18n/intl-context.js\";\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mCAGO;AACP,0CAIO;AACP,gDAIO;AACP,iCAIO;AACP,kCAIO;AACP,kCAIO;AACP,qCAIO;AACP,qDAIO;AACP,6BAIO;AACP,0BAAqD;AACrD,mCAIO;AACP,0BAAoD;","names":[]}
@@ -8,6 +8,7 @@ export { UsersManagement, UsersManagementProps } from './users-management.client
8
8
  export { AdminPortalDomainVerification, AdminPortalDomainVerificationProps } from './admin-portal-domain-verification.client.cjs';
9
9
  export { ApiKeys, ApiKeysProps } from './api-keys.client.cjs';
10
10
  export { Pipes, PipesProps } from './pipes.client.cjs';
11
+ export { DirectorySync, DirectorySyncProps } from './directory-sync.client.cjs';
11
12
  export { IntlContext as internal_IntlContext } from './lib/i18n/intl-context.cjs';
12
13
  export { OrganizationSwitcherLoading } from './lib/organization-switcher.cjs';
13
14
  export { AdminPortalSsoConnectionLoading } from './lib/admin-portal-sso-connection.cjs';
@@ -18,6 +19,7 @@ export { UsersManagementLoading } from './lib/users-management.cjs';
18
19
  export { AdminPortalDomainVerificationLoading } from './lib/admin-portal-domain-verification.cjs';
19
20
  export { ApiKeysLoading } from './lib/api-keys/api-keys.cjs';
20
21
  export { PipesLoading } from './lib/pipes.cjs';
22
+ export { DirectorySyncLoading } from './lib/directory-sync.cjs';
21
23
  import '@radix-ui/themes/props';
22
24
  import '@tanstack/react-query';
23
25
  import 'react';
@@ -100,7 +100,7 @@ function Content({ onClose, totpFactor }) {
100
100
  const securitySettings = (0, import_use_security_settings.useSecuritySettings)();
101
101
  const translate = (0, import_use_translation.useTranslation)();
102
102
  const [customError, setCustomError] = React.useState(null);
103
- const totp = hasQrCode(totpFactor) ? totpFactor.authenticationFactor.totp : void 0;
103
+ const totp = totpFactor?.authenticationFactor.totp != null && "qr_code" in totpFactor.authenticationFactor.totp ? totpFactor.authenticationFactor.totp : void 0;
104
104
  const verifyTotp = (0, import_endpoint.useVerifyTotpFactor)({
105
105
  mutation: {
106
106
  onSuccess: ({ success }) => {
@@ -229,7 +229,7 @@ function Content({ onClose, totpFactor }) {
229
229
  background: "var(--gray-2)",
230
230
  overflow: "hidden"
231
231
  },
232
- children: totp?.qr_code && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_themes.Box, { asChild: true, width: "100%", height: "auto", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
232
+ children: !!totp?.qr_code && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_themes.Box, { asChild: true, width: "100%", height: "auto", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
233
233
  "img",
234
234
  {
235
235
  alt: translate({
@@ -255,22 +255,28 @@ function Content({ onClose, totpFactor }) {
255
255
  description: "Question asking if user is unable to scan the QR code"
256
256
  }
257
257
  ) }),
258
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SecretDialog, { setupKey: totp?.secret ?? "", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
259
- import_elements.Button,
258
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
259
+ SecretDialog,
260
260
  {
261
- variant: "secondary",
262
- size: "1",
263
- disabled: verifyTotp.isPending || isSuccess,
261
+ setupKey: totp && "secret" in totp ? totp.secret : "",
264
262
  children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
265
- import_translation.Translation,
263
+ import_elements.Button,
266
264
  {
267
- defaultMessage: "View setup key",
268
- id: "q3eZjH",
269
- description: "Button text to view the manual setup key"
265
+ variant: "secondary",
266
+ size: "1",
267
+ disabled: verifyTotp.isPending || isSuccess,
268
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
269
+ import_translation.Translation,
270
+ {
271
+ defaultMessage: "View setup key",
272
+ id: "q3eZjH",
273
+ description: "Button text to view the manual setup key"
274
+ }
275
+ )
270
276
  }
271
277
  )
272
278
  }
273
- ) })
279
+ )
274
280
  ] })
275
281
  ] })
276
282
  ] }),
@@ -404,10 +410,6 @@ function getMutationErrorMessage(error) {
404
410
  }
405
411
  return message;
406
412
  }
407
- function hasQrCode(response) {
408
- const totp = response?.authenticationFactor.totp;
409
- return totp != null && "qr_code" in totp;
410
- }
411
413
  // Annotate the CommonJS export names for ESM import in node:
412
414
  0 && (module.exports = {
413
415
  AddMfaDialog
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/lib/add-mfa-dialog.tsx"],"sourcesContent":["\"use client\";\n\nimport {\n Box,\n Code,\n Flex,\n Grid,\n Link,\n Separator,\n Text,\n VisuallyHidden,\n} from \"@radix-ui/themes\";\nimport * as React from \"react\";\nimport { type ReactNode } from \"react\";\nimport * as Otp from \"./otp-input.js\";\nimport { Dialog, Button } from \"./elements.js\";\nimport {\n CreateTotpFactorResponse,\n CreateTotpFactorResponseAuthenticationFactorAllOfTotpAnyOf,\n useCreateTotpFactor,\n useVerifyTotpFactor,\n} from \"../api/endpoint.js\";\nimport { useElevatedAccessToken } from \"../api/api-provider.js\";\nimport { Form } from \"radix-ui\";\nimport { Marker } from \"./marker.js\";\nimport { CopyButton } from \"./copy-button.js\";\nimport { useSecuritySettings } from \"./use-security-settings.js\";\nimport { ElevatedAccess } from \"./elevated-access.js\";\nimport { SaveButton } from \"./save-button.js\";\nimport { useDialogClose } from \"./use-dialog-close.js\";\nimport { Translation } from \"./i18n/translation.js\";\nimport { useTranslation } from \"./i18n/use-translation.js\";\n\ninterface AddMfaDialogProps extends Dialog.RootProps {\n children?: ReactNode;\n onSuccess?: () => void;\n}\n\nexport function AddMfaDialog({\n children,\n onSuccess,\n ...props\n}: AddMfaDialogProps) {\n const [open, setOpen] = React.useState(false);\n const [manuallyTriggered, setManuallyTriggered] = React.useState(false);\n const { elevatedAccess } = useElevatedAccessToken();\n const createAuthFactor = useCreateTotpFactor();\n\n const handleVerified = async () => {\n await createAuthFactor.mutateAsync(undefined);\n };\n\n const onTriggerClick = (event: React.MouseEvent<HTMLButtonElement>) => {\n if (elevatedAccess && !createAuthFactor.data) {\n event.preventDefault();\n setManuallyTriggered(true);\n createAuthFactor.mutate(undefined, {\n onSuccess: () => {\n setOpen(true);\n },\n });\n } else {\n setManuallyTriggered(false);\n }\n };\n\n const handleClose = React.useCallback(() => {\n setOpen(false);\n }, []);\n\n return (\n <Dialog.Root\n {...props}\n open={props.open || open}\n onOpenChange={props.onOpenChange || setOpen}\n >\n <Dialog.Trigger\n onClick={onTriggerClick}\n // @ts-ignore I've to find a way to pass the loading state to the trigger\n loading={manuallyTriggered && createAuthFactor.isPending}\n >\n {children}\n </Dialog.Trigger>\n\n <Dialog.Content maxWidth=\"480px\">\n <ElevatedAccess onVerified={handleVerified}>\n <Content onClose={handleClose} totpFactor={createAuthFactor.data} />\n </ElevatedAccess>\n </Dialog.Content>\n </Dialog.Root>\n );\n}\n\ninterface ContentProps {\n totpFactor?: CreateTotpFactorResponse;\n onClose?: () => void;\n}\n\nfunction Content({ onClose, totpFactor }: ContentProps) {\n const securitySettings = useSecuritySettings();\n const translate = useTranslation();\n\n const [customError, setCustomError] = React.useState<string | null>(null);\n const totp = hasQrCode(totpFactor)\n ? totpFactor.authenticationFactor.totp\n : undefined;\n\n const verifyTotp = useVerifyTotpFactor({\n mutation: {\n onSuccess: ({ success }) => {\n if (!success) {\n setCustomError(\"Invalid passcode\");\n }\n },\n },\n });\n\n const serverError = verifyTotp.error || customError;\n const isSuccess = verifyTotp.isSuccess && !serverError;\n\n const handleSubmit = async (event: React.FormEvent<HTMLFormElement>) => {\n event.preventDefault();\n setCustomError(null);\n\n const formData = new FormData(event.currentTarget);\n const otpCode = formData.get(\"otp-code\")?.toString();\n\n verifyTotp.mutate({\n data: {\n authenticationChallengeId: totpFactor?.authenticationChallenge.id ?? \"\",\n code: otpCode ?? \"\",\n },\n });\n };\n\n useDialogClose(isSuccess, () => {\n securitySettings.update(\"Mfa\", true);\n });\n\n return (\n <>\n <Dialog.Title mb=\"5\">\n <Translation\n defaultMessage=\"Set up an authenticator app\"\n id=\"Eu+kuO\"\n description=\"Title for setting up two-factor authentication\"\n />\n </Dialog.Title>\n\n <Form.Root onSubmit={handleSubmit}>\n <Grid columns=\"auto 1fr\" rows=\"repeat(4, auto)\" gapX=\"3\" gapY=\"1\">\n <Grid\n rows=\"subgrid\"\n gridRow=\"span 4\"\n style={{ placeItems: \"center\" }}\n >\n {/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */}\n <Marker>1</Marker>\n <Separator\n orientation=\"vertical\"\n size=\"4\"\n style={{ width: \"2px\" }}\n />\n {/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */}\n <Marker>2</Marker>\n <div />\n </Grid>\n\n <Grid rows=\"subgrid\" gridRow=\"span 4\">\n <Text as=\"p\" size=\"3\" weight=\"bold\">\n <Translation\n defaultMessage=\"Scan the QR code\"\n id=\"fTSp5u\"\n description=\"Heading for the QR code scanning step in MFA setup\"\n />\n </Text>\n <Flex direction=\"column\" gap=\"1\">\n <Text as=\"p\" size=\"2\">\n <Translation\n defaultMessage=\"Use an authenticator app like {onep}, {google}, {authy}, or {microsoft} to scan the QR code below.\"\n id=\"8xwdwI\"\n description=\"Instructions for scanning the QR code with authenticator apps\"\n values={{\n onep: (\n <Link\n href=\"https://1password.com/\"\n rel=\"noopener noreferrer\"\n target=\"_blank\"\n // eslint-disable-next-line formatjs/no-literal-string-in-jsx\n >\n 1Password\n </Link>\n ),\n google: (\n <Link\n href=\"https://apps.apple.com/us/app/google-authenticator/id388497605\"\n rel=\"noopener noreferrer\"\n target=\"_blank\"\n // eslint-disable-next-line formatjs/no-literal-string-in-jsx\n >\n Google Authenticator\n </Link>\n ),\n authy: (\n <Link\n href=\"https://authy.com/\"\n rel=\"noopener noreferrer\"\n target=\"_blank\"\n // eslint-disable-next-line formatjs/no-literal-string-in-jsx\n >\n Authy\n </Link>\n ),\n microsoft: (\n <Link\n href=\"https://www.microsoft.com/en-gb/security/mobile-authenticator-app\"\n rel=\"noopener noreferrer\"\n target=\"_blank\"\n // eslint-disable-next-line formatjs/no-literal-string-in-jsx\n >\n Microsoft Authenticator\n </Link>\n ),\n }}\n />\n </Text>\n <Flex align=\"center\" gap=\"5\" my=\"5\">\n <Grid\n position=\"relative\"\n width=\"160px\"\n height=\"160px\"\n p=\"2\"\n style={{\n border: \"1px solid var(--gray-7)\",\n borderRadius: \"var(--radius-4)\",\n background: \"var(--gray-2)\",\n overflow: \"hidden\",\n }}\n >\n {totp?.qr_code && (\n <Box asChild width=\"100%\" height=\"auto\">\n <img\n alt={translate({\n defaultMessage: \"Scan this QR code to enroll\",\n description: \"Alt text for QR code image\",\n id: \"wpbqFJ\",\n })}\n aria-describedby=\"secret-note\"\n height=\"160\"\n src={totp.qr_code}\n style={{ userSelect: \"none\", background: \"white\" }}\n width=\"160\"\n />\n </Box>\n )}\n </Grid>\n\n <Flex direction=\"column\" gap=\"1\" align=\"start\">\n <Text color=\"gray\" id=\"secret-note\" size=\"2\">\n <Translation\n defaultMessage=\"Can't scan the code?\"\n id=\"6/cdcS\"\n description=\"Question asking if user is unable to scan the QR code\"\n />\n </Text>\n\n <SecretDialog setupKey={totp?.secret ?? \"\"}>\n <Button\n variant=\"secondary\"\n size=\"1\"\n disabled={verifyTotp.isPending || isSuccess}\n >\n <Translation\n defaultMessage=\"View setup key\"\n id=\"q3eZjH\"\n description=\"Button text to view the manual setup key\"\n />\n </Button>\n </SecretDialog>\n </Flex>\n </Flex>\n </Flex>\n <Text as=\"p\" size=\"3\" weight=\"bold\">\n <Translation\n defaultMessage=\"Get verification passcode\"\n id=\"1kRd2b\"\n description=\"Heading for entering the verification code step\"\n />\n </Text>\n <Flex direction=\"column\" gap=\"4\">\n <Text as=\"p\" size=\"2\">\n <Translation\n defaultMessage=\"Enter the 6-digit passcode from your authenticator app.\"\n id=\"4/66bS\"\n description=\"Instructions for entering the verification passcode\"\n />\n </Text>\n\n <Flex direction=\"column\" gap=\"2\">\n <Otp.Root\n autoSubmit\n gap=\"3\"\n justify=\"start\"\n name=\"otp-code\"\n rows=\"48px\"\n columns=\"repeat(6, 48px)\"\n readOnly={verifyTotp.isPending || isSuccess}\n >\n <Otp.Input required autoFocus autoComplete=\"off\" />\n <Otp.Input required />\n <Otp.Input required />\n <Otp.Input required />\n <Otp.Input required />\n <Otp.Input required />\n </Otp.Root>\n\n {serverError && (\n <Text size=\"2\" color=\"red\">\n {getMutationErrorMessage(serverError)}\n </Text>\n )}\n </Flex>\n </Flex>\n </Grid>\n </Grid>\n\n <Flex mt=\"5\" gap=\"3\" justify=\"end\">\n <Dialog.Close>\n <Button\n variant=\"secondary\"\n disabled={verifyTotp.isPending || isSuccess}\n >\n <Translation\n defaultMessage=\"Cancel\"\n id=\"84pAvU\"\n description=\"Button text to cancel MFA setup\"\n />\n </Button>\n </Dialog.Close>\n\n <SaveButton\n type=\"submit\"\n loading={verifyTotp.isPending}\n done={isSuccess}\n onDone={onClose}\n >\n <Translation\n defaultMessage=\"Confirm\"\n id=\"WHthZi\"\n description=\"Button text to confirm MFA setup\"\n />\n </SaveButton>\n </Flex>\n </Form.Root>\n\n {/* mirror errors in a live region */}\n <VisuallyHidden asChild>\n <section aria-live=\"polite\">\n {getMutationErrorMessage(serverError)}\n </section>\n </VisuallyHidden>\n </>\n );\n}\n\ninterface SecretDialogProps extends React.PropsWithChildren {\n setupKey: string;\n}\n\nfunction SecretDialog({ children, setupKey }: SecretDialogProps) {\n return (\n <Dialog.Root>\n <Dialog.Trigger>{children}</Dialog.Trigger>\n <Dialog.Content\n maxWidth=\"90vw\"\n size={{ initial: \"3\", sm: \"4\" }}\n minWidth=\"300px\"\n width=\"fit-content\"\n >\n <Dialog.Title size=\"2\" weight=\"regular\">\n <Translation\n defaultMessage=\"Your setup key\"\n id=\"LleqNP\"\n description=\"Title for dialog showing the manual setup key\"\n />\n </Dialog.Title>\n <Dialog.Description>\n <Text size=\"6\">\n <Code variant=\"ghost\" style={{ letterSpacing: \"0.15rem\" }}>\n {setupKey}\n </Code>\n </Text>\n </Dialog.Description>\n\n <Flex align=\"center\" gap=\"3\" justify=\"end\" mt=\"5\">\n <Dialog.Close>\n <CopyButton value={setupKey}>\n <Translation\n defaultMessage=\"Copy and close\"\n id=\"EyjGir\"\n description=\"Button text to copy setup key and close dialog\"\n />\n </CopyButton>\n </Dialog.Close>\n </Flex>\n </Dialog.Content>\n </Dialog.Root>\n );\n}\n\nfunction getMutationErrorMessage(error: unknown) {\n let message = \"Something went wrong, please try again\";\n\n if (typeof error === \"string\") {\n message = error;\n }\n\n if (error instanceof Error) {\n message = error.message;\n }\n\n if (\n typeof error === \"object\" &&\n error !== null &&\n \"message\" in error &&\n typeof error.message === \"string\"\n ) {\n message = error.message;\n }\n\n if (message === \"Invalid passcode\") {\n message = \"Invalid passcode, please try again\";\n }\n\n return message;\n}\n\nfunction hasQrCode(\n response?: CreateTotpFactorResponse,\n): response is CreateTotpFactorResponse & {\n authenticationFactor: {\n totp: NonNullable<CreateTotpFactorResponseAuthenticationFactorAllOfTotpAnyOf>;\n };\n} {\n const totp = response?.authenticationFactor.totp;\n return totp != null && \"qr_code\" in totp;\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../../src/lib/add-mfa-dialog.tsx"],"sourcesContent":["\"use client\";\n\nimport {\n Box,\n Code,\n Flex,\n Grid,\n Link,\n Separator,\n Text,\n VisuallyHidden,\n} from \"@radix-ui/themes\";\nimport * as React from \"react\";\nimport { type ReactNode } from \"react\";\nimport * as Otp from \"./otp-input.js\";\nimport { Dialog, Button } from \"./elements.js\";\nimport {\n CreateTotpFactorResponse,\n useCreateTotpFactor,\n useVerifyTotpFactor,\n} from \"../api/endpoint.js\";\nimport { useElevatedAccessToken } from \"../api/api-provider.js\";\nimport { Form } from \"radix-ui\";\nimport { Marker } from \"./marker.js\";\nimport { CopyButton } from \"./copy-button.js\";\nimport { useSecuritySettings } from \"./use-security-settings.js\";\nimport { ElevatedAccess } from \"./elevated-access.js\";\nimport { SaveButton } from \"./save-button.js\";\nimport { useDialogClose } from \"./use-dialog-close.js\";\nimport { Translation } from \"./i18n/translation.js\";\nimport { useTranslation } from \"./i18n/use-translation.js\";\n\ninterface AddMfaDialogProps extends Dialog.RootProps {\n children?: ReactNode;\n onSuccess?: () => void;\n}\n\nexport function AddMfaDialog({\n children,\n onSuccess,\n ...props\n}: AddMfaDialogProps) {\n const [open, setOpen] = React.useState(false);\n const [manuallyTriggered, setManuallyTriggered] = React.useState(false);\n const { elevatedAccess } = useElevatedAccessToken();\n const createAuthFactor = useCreateTotpFactor();\n\n const handleVerified = async () => {\n await createAuthFactor.mutateAsync(undefined);\n };\n\n const onTriggerClick = (event: React.MouseEvent<HTMLButtonElement>) => {\n if (elevatedAccess && !createAuthFactor.data) {\n event.preventDefault();\n setManuallyTriggered(true);\n createAuthFactor.mutate(undefined, {\n onSuccess: () => {\n setOpen(true);\n },\n });\n } else {\n setManuallyTriggered(false);\n }\n };\n\n const handleClose = React.useCallback(() => {\n setOpen(false);\n }, []);\n\n return (\n <Dialog.Root\n {...props}\n open={props.open || open}\n onOpenChange={props.onOpenChange || setOpen}\n >\n <Dialog.Trigger\n onClick={onTriggerClick}\n // @ts-ignore I've to find a way to pass the loading state to the trigger\n loading={manuallyTriggered && createAuthFactor.isPending}\n >\n {children}\n </Dialog.Trigger>\n\n <Dialog.Content maxWidth=\"480px\">\n <ElevatedAccess onVerified={handleVerified}>\n <Content onClose={handleClose} totpFactor={createAuthFactor.data} />\n </ElevatedAccess>\n </Dialog.Content>\n </Dialog.Root>\n );\n}\n\ninterface ContentProps {\n totpFactor?: CreateTotpFactorResponse;\n onClose?: () => void;\n}\n\nfunction Content({ onClose, totpFactor }: ContentProps) {\n const securitySettings = useSecuritySettings();\n const translate = useTranslation();\n\n const [customError, setCustomError] = React.useState<string | null>(null);\n const totp =\n totpFactor?.authenticationFactor.totp != null &&\n \"qr_code\" in totpFactor.authenticationFactor.totp\n ? totpFactor.authenticationFactor.totp\n : undefined;\n\n const verifyTotp = useVerifyTotpFactor({\n mutation: {\n onSuccess: ({ success }) => {\n if (!success) {\n setCustomError(\"Invalid passcode\");\n }\n },\n },\n });\n\n const serverError = verifyTotp.error || customError;\n const isSuccess = verifyTotp.isSuccess && !serverError;\n\n const handleSubmit = async (event: React.FormEvent<HTMLFormElement>) => {\n event.preventDefault();\n setCustomError(null);\n\n const formData = new FormData(event.currentTarget);\n const otpCode = formData.get(\"otp-code\")?.toString();\n\n verifyTotp.mutate({\n data: {\n authenticationChallengeId: totpFactor?.authenticationChallenge.id ?? \"\",\n code: otpCode ?? \"\",\n },\n });\n };\n\n useDialogClose(isSuccess, () => {\n securitySettings.update(\"Mfa\", true);\n });\n\n return (\n <>\n <Dialog.Title mb=\"5\">\n <Translation\n defaultMessage=\"Set up an authenticator app\"\n id=\"Eu+kuO\"\n description=\"Title for setting up two-factor authentication\"\n />\n </Dialog.Title>\n\n <Form.Root onSubmit={handleSubmit}>\n <Grid columns=\"auto 1fr\" rows=\"repeat(4, auto)\" gapX=\"3\" gapY=\"1\">\n <Grid\n rows=\"subgrid\"\n gridRow=\"span 4\"\n style={{ placeItems: \"center\" }}\n >\n {/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */}\n <Marker>1</Marker>\n <Separator\n orientation=\"vertical\"\n size=\"4\"\n style={{ width: \"2px\" }}\n />\n {/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */}\n <Marker>2</Marker>\n <div />\n </Grid>\n\n <Grid rows=\"subgrid\" gridRow=\"span 4\">\n <Text as=\"p\" size=\"3\" weight=\"bold\">\n <Translation\n defaultMessage=\"Scan the QR code\"\n id=\"fTSp5u\"\n description=\"Heading for the QR code scanning step in MFA setup\"\n />\n </Text>\n <Flex direction=\"column\" gap=\"1\">\n <Text as=\"p\" size=\"2\">\n <Translation\n defaultMessage=\"Use an authenticator app like {onep}, {google}, {authy}, or {microsoft} to scan the QR code below.\"\n id=\"8xwdwI\"\n description=\"Instructions for scanning the QR code with authenticator apps\"\n values={{\n onep: (\n <Link\n href=\"https://1password.com/\"\n rel=\"noopener noreferrer\"\n target=\"_blank\"\n // eslint-disable-next-line formatjs/no-literal-string-in-jsx\n >\n 1Password\n </Link>\n ),\n google: (\n <Link\n href=\"https://apps.apple.com/us/app/google-authenticator/id388497605\"\n rel=\"noopener noreferrer\"\n target=\"_blank\"\n // eslint-disable-next-line formatjs/no-literal-string-in-jsx\n >\n Google Authenticator\n </Link>\n ),\n authy: (\n <Link\n href=\"https://authy.com/\"\n rel=\"noopener noreferrer\"\n target=\"_blank\"\n // eslint-disable-next-line formatjs/no-literal-string-in-jsx\n >\n Authy\n </Link>\n ),\n microsoft: (\n <Link\n href=\"https://www.microsoft.com/en-gb/security/mobile-authenticator-app\"\n rel=\"noopener noreferrer\"\n target=\"_blank\"\n // eslint-disable-next-line formatjs/no-literal-string-in-jsx\n >\n Microsoft Authenticator\n </Link>\n ),\n }}\n />\n </Text>\n <Flex align=\"center\" gap=\"5\" my=\"5\">\n <Grid\n position=\"relative\"\n width=\"160px\"\n height=\"160px\"\n p=\"2\"\n style={{\n border: \"1px solid var(--gray-7)\",\n borderRadius: \"var(--radius-4)\",\n background: \"var(--gray-2)\",\n overflow: \"hidden\",\n }}\n >\n {!!totp?.qr_code && (\n <Box asChild width=\"100%\" height=\"auto\">\n <img\n alt={translate({\n defaultMessage: \"Scan this QR code to enroll\",\n description: \"Alt text for QR code image\",\n id: \"wpbqFJ\",\n })}\n aria-describedby=\"secret-note\"\n height=\"160\"\n src={totp.qr_code}\n style={{ userSelect: \"none\", background: \"white\" }}\n width=\"160\"\n />\n </Box>\n )}\n </Grid>\n\n <Flex direction=\"column\" gap=\"1\" align=\"start\">\n <Text color=\"gray\" id=\"secret-note\" size=\"2\">\n <Translation\n defaultMessage=\"Can't scan the code?\"\n id=\"6/cdcS\"\n description=\"Question asking if user is unable to scan the QR code\"\n />\n </Text>\n\n <SecretDialog\n setupKey={totp && \"secret\" in totp ? totp.secret : \"\"}\n >\n <Button\n variant=\"secondary\"\n size=\"1\"\n disabled={verifyTotp.isPending || isSuccess}\n >\n <Translation\n defaultMessage=\"View setup key\"\n id=\"q3eZjH\"\n description=\"Button text to view the manual setup key\"\n />\n </Button>\n </SecretDialog>\n </Flex>\n </Flex>\n </Flex>\n <Text as=\"p\" size=\"3\" weight=\"bold\">\n <Translation\n defaultMessage=\"Get verification passcode\"\n id=\"1kRd2b\"\n description=\"Heading for entering the verification code step\"\n />\n </Text>\n <Flex direction=\"column\" gap=\"4\">\n <Text as=\"p\" size=\"2\">\n <Translation\n defaultMessage=\"Enter the 6-digit passcode from your authenticator app.\"\n id=\"4/66bS\"\n description=\"Instructions for entering the verification passcode\"\n />\n </Text>\n\n <Flex direction=\"column\" gap=\"2\">\n <Otp.Root\n autoSubmit\n gap=\"3\"\n justify=\"start\"\n name=\"otp-code\"\n rows=\"48px\"\n columns=\"repeat(6, 48px)\"\n readOnly={verifyTotp.isPending || isSuccess}\n >\n <Otp.Input required autoFocus autoComplete=\"off\" />\n <Otp.Input required />\n <Otp.Input required />\n <Otp.Input required />\n <Otp.Input required />\n <Otp.Input required />\n </Otp.Root>\n\n {serverError && (\n <Text size=\"2\" color=\"red\">\n {getMutationErrorMessage(serverError)}\n </Text>\n )}\n </Flex>\n </Flex>\n </Grid>\n </Grid>\n\n <Flex mt=\"5\" gap=\"3\" justify=\"end\">\n <Dialog.Close>\n <Button\n variant=\"secondary\"\n disabled={verifyTotp.isPending || isSuccess}\n >\n <Translation\n defaultMessage=\"Cancel\"\n id=\"84pAvU\"\n description=\"Button text to cancel MFA setup\"\n />\n </Button>\n </Dialog.Close>\n\n <SaveButton\n type=\"submit\"\n loading={verifyTotp.isPending}\n done={isSuccess}\n onDone={onClose}\n >\n <Translation\n defaultMessage=\"Confirm\"\n id=\"WHthZi\"\n description=\"Button text to confirm MFA setup\"\n />\n </SaveButton>\n </Flex>\n </Form.Root>\n\n {/* mirror errors in a live region */}\n <VisuallyHidden asChild>\n <section aria-live=\"polite\">\n {getMutationErrorMessage(serverError)}\n </section>\n </VisuallyHidden>\n </>\n );\n}\n\ninterface SecretDialogProps extends React.PropsWithChildren {\n setupKey: string;\n}\n\nfunction SecretDialog({ children, setupKey }: SecretDialogProps) {\n return (\n <Dialog.Root>\n <Dialog.Trigger>{children}</Dialog.Trigger>\n <Dialog.Content\n maxWidth=\"90vw\"\n size={{ initial: \"3\", sm: \"4\" }}\n minWidth=\"300px\"\n width=\"fit-content\"\n >\n <Dialog.Title size=\"2\" weight=\"regular\">\n <Translation\n defaultMessage=\"Your setup key\"\n id=\"LleqNP\"\n description=\"Title for dialog showing the manual setup key\"\n />\n </Dialog.Title>\n <Dialog.Description>\n <Text size=\"6\">\n <Code variant=\"ghost\" style={{ letterSpacing: \"0.15rem\" }}>\n {setupKey}\n </Code>\n </Text>\n </Dialog.Description>\n\n <Flex align=\"center\" gap=\"3\" justify=\"end\" mt=\"5\">\n <Dialog.Close>\n <CopyButton value={setupKey}>\n <Translation\n defaultMessage=\"Copy and close\"\n id=\"EyjGir\"\n description=\"Button text to copy setup key and close dialog\"\n />\n </CopyButton>\n </Dialog.Close>\n </Flex>\n </Dialog.Content>\n </Dialog.Root>\n );\n}\n\nfunction getMutationErrorMessage(error: unknown) {\n let message = \"Something went wrong, please try again\";\n\n if (typeof error === \"string\") {\n message = error;\n }\n\n if (error instanceof Error) {\n message = error.message;\n }\n\n if (\n typeof error === \"object\" &&\n error !== null &&\n \"message\" in error &&\n typeof error.message === \"string\"\n ) {\n message = error.message;\n }\n\n if (message === \"Invalid passcode\") {\n message = \"Invalid passcode, please try again\";\n }\n\n return message;\n}\n"],"mappings":"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","names":[]}
@@ -233,7 +233,6 @@ function SessionInfo({
233
233
  }
234
234
  function AdminPortalOpenButton({
235
235
  isPending,
236
- href,
237
236
  initConfig
238
237
  }) {
239
238
  const { connectionStatus } = useAdminPortalSsoConnectionContext();
@@ -272,13 +271,6 @@ function AdminPortalOpenButton({
272
271
  return (0, import_utils.unreachable)(connectionStatus);
273
272
  }
274
273
  })();
275
- if (href) {
276
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_elements.Button, { variant: "secondary", asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("a", { href, target: "_blank", rel: "noopener noreferrer", children: [
277
- label,
278
- " ",
279
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_icons.ExternalLinkIcon, { "aria-hidden": true })
280
- ] }) });
281
- }
282
274
  return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
283
275
  import_elements.Button,
284
276
  {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/lib/admin-portal-sso-connection.tsx"],"sourcesContent":["\"use client\";\n\nimport * as React from \"react\";\nimport { Box, Card, Flex, Text } from \"@radix-ui/themes\";\nimport { Button, Skeleton } from \"./elements.js\";\nimport { IconPanel } from \"./icon-panel.js\";\nimport {\n ExternalLinkIcon,\n InfoCircledIcon,\n Cross2Icon,\n} from \"@radix-ui/react-icons\";\nimport * as CardList from \"./card-list.js\";\nimport { ProviderIcon } from \"./provider-icon.js\";\nimport {\n getIdentityProviderName,\n type IdentityProvider,\n} from \"./identity-providers.js\";\nimport { Status } from \"./status.js\";\nimport {\n getDomProps,\n unreachable,\n type WidgetRootState,\n type WidgetRootDomProps,\n} from \"./utils.js\";\nimport { Translation } from \"./i18n/translation.js\";\nimport { useTranslation } from \"./i18n/use-translation.js\";\nimport { getErrorMessage } from \"./generic-error.js\";\n\ninterface NotConfiguredProps {\n connectionStatus: \"NotConfigured\";\n identityProvider?: never;\n expiryDate?: never;\n}\n\ninterface InactiveProps {\n connectionStatus: \"Inactive\";\n identityProvider: IdentityProvider;\n expiryDate?: never;\n}\n\ninterface ActiveProps {\n connectionStatus: \"Active\";\n identityProvider: IdentityProvider;\n expiryDate?: never;\n}\n\ninterface RequiresActionProps {\n connectionStatus: \"Expired\" | \"Expiring\";\n identityProvider: IdentityProvider;\n expiryDate: Date | null;\n}\n\nexport type AdminPortalSsoConnectionStatusProps =\n | NotConfiguredProps\n | InactiveProps\n | ActiveProps\n | RequiresActionProps;\n\ntype AdminPortalSsoConnectionProps = WidgetRootDomProps &\n AdminPortalSsoConnectionStatusProps & {\n currentDate: Date | null;\n lastSession: Date | null;\n adminPortalOpenButton: React.ReactNode;\n };\n\ninterface AdminPortalSsoConnectionContextValue {\n connectionStatus: AdminPortalSsoConnectionStatusProps[\"connectionStatus\"];\n}\n\nconst AdminPortalSsoConnectionContext =\n React.createContext<AdminPortalSsoConnectionContextValue | null>(null);\nAdminPortalSsoConnectionContext.displayName = \"AdminPortalSsoConnectionContext\";\n\nfunction useAdminPortalSsoConnectionContext() {\n const context = React.useContext(AdminPortalSsoConnectionContext);\n if (!context) {\n throw new Error(\n \"useAdminPortalSsoConnectionContext must be used within a AdminPortalSsoConnectionContext provider\",\n );\n }\n return context;\n}\n\nconst AdminPortalSsoConnection: React.FC<AdminPortalSsoConnectionProps> = ({\n currentDate,\n connectionStatus,\n identityProvider,\n expiryDate,\n lastSession,\n adminPortalOpenButton,\n ...domProps\n}) => {\n return (\n <CardList.Root size=\"2\" {...getWidgetRootDomProps(\"resolved\", domProps)}>\n <AdminPortalSsoConnectionContext.Provider value={{ connectionStatus }}>\n <CardList.Item>\n <Flex direction=\"row\" justify=\"between\" align=\"center\" gap=\"2\">\n {(() => {\n if (connectionStatus === \"NotConfigured\") {\n return (\n <>\n <Text size=\"2\" color=\"gray\">\n <Translation\n defaultMessage=\"You haven't set up Single Sign-On yet.\"\n id=\"KDs1Ib\"\n description=\"Empty state message when SSO is not configured\"\n />\n </Text>\n {adminPortalOpenButton}\n </>\n );\n }\n\n return (\n <>\n <SessionInfo\n connectionStatus={connectionStatus}\n identityProvider={identityProvider}\n lastSession={lastSession}\n currentDate={currentDate}\n />\n <Flex gap=\"5\" align=\"center\">\n <SsoStatus status={connectionStatus} />\n {adminPortalOpenButton}\n </Flex>\n </>\n );\n })()}\n </Flex>\n </CardList.Item>\n {connectionStatus === \"Expired\" && (\n <CardList.Item>\n <Flex align=\"start\" gap=\"2\">\n <Box asChild mt=\"2px\" flexShrink=\"0\">\n <InfoCircledIcon color=\"gray\" />\n </Box>\n {(() => {\n if (connectionStatus === \"Expired\") {\n return (\n <Text size=\"2\" color=\"gray\">\n {(() => {\n if (!expiryDate) {\n return (\n <Translation\n defaultMessage=\"The SAML response signing certificate has expired. Users won't be able to sign-in to the application until the certificate is renewed.\"\n id=\"5tX19v\"\n description=\"Error message when SAML certificate has expired (no date)\"\n />\n );\n }\n\n return (\n <Translation\n defaultMessage=\"The SAML response signing certificate expired on {expiryDate}. Users won't be able to sign-in to the application until the certificate is renewed.\"\n id=\"vmTW/h\"\n description=\"Error message when SAML certificate has expired with date\"\n values={{\n expiryDate: (\n <Text weight=\"bold\" as=\"span\">\n {expiryDate?.toLocaleString(\"en-US\", {\n month: \"long\",\n day: \"numeric\",\n year: \"numeric\",\n })}\n </Text>\n ),\n }}\n />\n );\n })()}\n </Text>\n );\n }\n\n if (connectionStatus === \"Expiring\") {\n return (\n <Text size=\"2\" color=\"gray\">\n {(() => {\n if (!expiryDate) {\n return (\n <Translation\n defaultMessage=\"The SAML response signing certificate is expiring soon. When expired, users won't be able to sign-in.\"\n id=\"3dgA5f\"\n description=\"Warning message when SAML certificate is expiring soon (no date)\"\n />\n );\n }\n\n return (\n <Translation\n defaultMessage=\"The SAML response signing certificate will expire on {expiryDate}. When expired, users won't be able to sign-in.\"\n id=\"xT9Exy\"\n description=\"Warning message when SAML certificate is expiring with date\"\n values={{\n expiryDate: (\n <Text weight=\"bold\" as=\"span\">\n {expiryDate?.toLocaleString(\"en-US\", {\n month: \"long\",\n day: \"numeric\",\n year: \"numeric\",\n })}\n </Text>\n ),\n }}\n />\n );\n })()}\n </Text>\n );\n }\n })()}\n </Flex>\n </CardList.Item>\n )}\n </AdminPortalSsoConnectionContext.Provider>\n </CardList.Root>\n );\n};\n\nfunction SsoStatus({\n status,\n}: {\n status: AdminPortalSsoConnectionStatusProps[\"connectionStatus\"];\n}) {\n if (status === \"NotConfigured\") {\n return null;\n }\n\n if (status === \"Inactive\") {\n return (\n <Status state=\"waiting\">\n <Translation\n defaultMessage=\"Setup in progress\"\n id=\"MQR5mR\"\n description=\"Status label when SSO setup is incomplete\"\n />\n </Status>\n );\n }\n\n if (status === \"Expired\") {\n return (\n <Status state=\"error\">\n <Translation\n defaultMessage=\"Requires action\"\n id=\"Yo2vHC\"\n description=\"Status label when SSO requires attention\"\n />\n </Status>\n );\n }\n\n if (status === \"Active\" || status === \"Expiring\") {\n return (\n <Status state=\"success\">\n <Translation\n defaultMessage=\"Connected\"\n id=\"8S+Cyw\"\n description=\"Status label when SSO is active\"\n />\n </Status>\n );\n }\n\n return unreachable(status);\n}\n\nfunction SessionInfo({\n currentDate,\n identityProvider,\n lastSession,\n connectionStatus,\n}: {\n identityProvider: IdentityProvider;\n lastSession: Date | null;\n currentDate: Date | null;\n connectionStatus: AdminPortalSsoConnectionStatusProps[\"connectionStatus\"];\n}) {\n const relativeTimeString = React.useMemo(() => {\n if (\n !lastSession ||\n !currentDate ||\n connectionStatus === \"NotConfigured\" ||\n connectionStatus === \"Inactive\"\n ) {\n return null;\n }\n\n return getRelativeTimeString(currentDate, lastSession);\n }, [lastSession, currentDate, connectionStatus]);\n\n return (\n <Flex gap=\"4\" align=\"center\">\n <IconPanel color=\"panel\">\n <ProviderIcon provider={identityProvider} size=\"2\" />\n </IconPanel>\n {lastSession ? (\n <Flex direction=\"column\">\n <Text size=\"2\" weight=\"bold\">\n {getIdentityProviderName(identityProvider)}\n </Text>\n {relativeTimeString ? (\n <Text color=\"gray\" size=\"2\">\n <Translation\n defaultMessage=\"Last session {relativeTime}\"\n id=\"yN72Gc\"\n description=\"Label showing when the last SSO session occurred\"\n values={{ relativeTime: relativeTimeString }}\n />\n </Text>\n ) : null}\n </Flex>\n ) : (\n <Text size=\"2\" weight=\"bold\">\n {getIdentityProviderName(identityProvider)}\n </Text>\n )}\n </Flex>\n );\n}\n\nfunction AdminPortalOpenButton({\n isPending,\n href,\n initConfig,\n}: {\n isPending: boolean;\n href: string | null;\n initConfig: () => void;\n}) {\n const { connectionStatus } = useAdminPortalSsoConnectionContext();\n const label = (() => {\n switch (connectionStatus) {\n case \"NotConfigured\":\n return (\n <Translation\n defaultMessage=\"Set up SSO\"\n id=\"MtkNQO\"\n description=\"Button label to start SSO setup\"\n />\n );\n case \"Inactive\":\n return (\n <Translation\n defaultMessage=\"Continue setup\"\n id=\"HFxrbY\"\n description=\"Button label to continue incomplete SSO setup\"\n />\n );\n case \"Active\":\n case \"Expiring\":\n case \"Expired\":\n return (\n <Translation\n defaultMessage=\"Manage\"\n id=\"T1VKzP\"\n description=\"Button label to manage SSO settings\"\n />\n );\n default:\n return unreachable(connectionStatus);\n }\n })();\n\n if (href) {\n return (\n <Button variant=\"secondary\" asChild>\n <a href={href} target=\"_blank\" rel=\"noopener noreferrer\">\n {label} <ExternalLinkIcon aria-hidden />\n </a>\n </Button>\n );\n }\n\n return (\n <Button\n variant=\"secondary\"\n loading={isPending}\n disabled={isPending}\n onClick={initConfig}\n >\n {label} <ExternalLinkIcon aria-hidden />\n </Button>\n );\n}\n\ninterface AdminPortalSsoConnectionLoadingProps extends WidgetRootDomProps {}\n\nconst AdminPortalSsoConnectionLoading: React.FC<\n AdminPortalSsoConnectionLoadingProps\n> = (props) => {\n return (\n <Card size=\"2\" {...getWidgetRootDomProps(\"loading\", props)}>\n <Flex direction=\"row\" justify=\"between\" align=\"center\" gap=\"2\">\n <Flex gap=\"4\" align=\"center\">\n <Skeleton>\n <IconPanel color=\"panel\">\n <ProviderIcon provider=\"okta\" size=\"2\" />\n </IconPanel>\n </Skeleton>\n <Flex direction=\"column\" gap=\"1\" my=\"-4px\">\n <Skeleton>\n {/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */}\n <Text size=\"1\">Okta</Text>\n </Skeleton>\n <Skeleton>\n {/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */}\n <Text size=\"1\">Last session 10 minutes ago</Text>\n </Skeleton>\n </Flex>\n </Flex>\n <Flex gap=\"5\" align=\"center\">\n <Skeleton>\n {/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */}\n <Status state=\"error\">Requires action</Status>\n </Skeleton>\n <Skeleton>\n {/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */}\n <Button variant=\"secondary\">\n Manage <ExternalLinkIcon aria-hidden />\n </Button>\n </Skeleton>\n </Flex>\n </Flex>\n </Card>\n );\n};\n\ninterface AdminPortalSsoConnectionErrorProps extends WidgetRootDomProps {\n error: unknown;\n}\n\nconst AdminPortalSsoConnectionError: React.FC<\n AdminPortalSsoConnectionErrorProps\n> = ({ error, ...domProps }) => {\n const translate = useTranslation();\n React.useEffect(() => {\n console.error(error);\n }, [error]);\n\n const { heading, message } = getErrorMessage(error, translate);\n\n return (\n <Card size=\"2\" {...getWidgetRootDomProps(\"error\", domProps)}>\n <Flex direction=\"row\" justify=\"between\" align=\"center\" gap=\"2\">\n <Flex gap=\"4\" align=\"center\">\n <Flex\n align=\"center\"\n justify=\"center\"\n width=\"24px\"\n height=\"24px\"\n style={{\n borderRadius: \"9999px\",\n backgroundColor: \"var(--red-a4)\",\n color: \"var(--red-a11)\",\n flexShrink: 0,\n }}\n >\n <Cross2Icon width=\"18px\" height=\"18px\" />\n </Flex>\n <Flex direction=\"column\">\n <Text size=\"2\" weight=\"bold\">\n {heading}\n </Text>\n <Text size=\"2\" color=\"gray\">\n {message}\n </Text>\n </Flex>\n </Flex>\n </Flex>\n </Card>\n );\n};\n\nfunction getRelativeTimeString(\n currentDate: Date | null,\n lastSession: Date | null,\n) {\n if (!currentDate || !lastSession) {\n return null;\n }\n\n const rtf = new Intl.RelativeTimeFormat(\"en\", { numeric: \"auto\" });\n const diff = lastSession.getTime() - currentDate.getTime();\n\n const diffSeconds = Math.round(diff / 1000);\n const diffMinutes = Math.round(diffSeconds / 60);\n const diffHours = Math.round(diffMinutes / 60);\n const diffDays = Math.round(diffHours / 24);\n const diffMonths = Math.round(diffDays / 30);\n const diffYears = Math.round(diffMonths / 12);\n\n if (Math.abs(diffSeconds) < 60) {\n return \"now\";\n }\n\n if (Math.abs(diffMinutes) < 60) {\n return rtf.format(diffMinutes, \"minute\");\n }\n\n if (Math.abs(diffHours) < 24) {\n return rtf.format(diffHours, \"hour\");\n }\n\n if (Math.abs(diffDays) < 30) {\n return rtf.format(diffDays, \"day\");\n }\n\n if (Math.abs(diffMonths) < 12) {\n return rtf.format(diffMonths, \"month\");\n }\n\n return rtf.format(diffYears, \"year\");\n}\n\nfunction getWidgetRootDomProps(\n state: WidgetRootState,\n domProps: WidgetRootDomProps,\n) {\n return getDomProps({\n ...domProps,\n isWidgetRoot: true,\n widgetId: \"admin-portal-sso-connection\",\n widgetState: state,\n });\n}\n\nexport type {\n AdminPortalSsoConnectionProps,\n AdminPortalSsoConnectionLoadingProps,\n AdminPortalSsoConnectionErrorProps,\n};\nexport {\n AdminPortalSsoConnection,\n AdminPortalSsoConnectionLoading,\n AdminPortalSsoConnectionError,\n /** @internal */\n AdminPortalOpenButton,\n};\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../../src/lib/admin-portal-sso-connection.tsx"],"sourcesContent":["\"use client\";\n\nimport * as React from \"react\";\nimport { Box, Card, Flex, Text } from \"@radix-ui/themes\";\nimport { Button, Skeleton } from \"./elements.js\";\nimport { IconPanel } from \"./icon-panel.js\";\nimport {\n ExternalLinkIcon,\n InfoCircledIcon,\n Cross2Icon,\n} from \"@radix-ui/react-icons\";\nimport * as CardList from \"./card-list.js\";\nimport { ProviderIcon } from \"./provider-icon.js\";\nimport {\n getIdentityProviderName,\n type IdentityProvider,\n} from \"./identity-providers.js\";\nimport { Status } from \"./status.js\";\nimport {\n getDomProps,\n unreachable,\n type WidgetRootState,\n type WidgetRootDomProps,\n} from \"./utils.js\";\nimport { Translation } from \"./i18n/translation.js\";\nimport { useTranslation } from \"./i18n/use-translation.js\";\nimport { getErrorMessage } from \"./generic-error.js\";\n\ninterface NotConfiguredProps {\n connectionStatus: \"NotConfigured\";\n identityProvider?: never;\n expiryDate?: never;\n}\n\ninterface InactiveProps {\n connectionStatus: \"Inactive\";\n identityProvider: IdentityProvider;\n expiryDate?: never;\n}\n\ninterface ActiveProps {\n connectionStatus: \"Active\";\n identityProvider: IdentityProvider;\n expiryDate?: never;\n}\n\ninterface RequiresActionProps {\n connectionStatus: \"Expired\" | \"Expiring\";\n identityProvider: IdentityProvider;\n expiryDate: Date | null;\n}\n\nexport type AdminPortalSsoConnectionStatusProps =\n | NotConfiguredProps\n | InactiveProps\n | ActiveProps\n | RequiresActionProps;\n\ntype AdminPortalSsoConnectionProps = WidgetRootDomProps &\n AdminPortalSsoConnectionStatusProps & {\n currentDate: Date | null;\n lastSession: Date | null;\n adminPortalOpenButton: React.ReactNode;\n };\n\ninterface AdminPortalSsoConnectionContextValue {\n connectionStatus: AdminPortalSsoConnectionStatusProps[\"connectionStatus\"];\n}\n\nconst AdminPortalSsoConnectionContext =\n React.createContext<AdminPortalSsoConnectionContextValue | null>(null);\nAdminPortalSsoConnectionContext.displayName = \"AdminPortalSsoConnectionContext\";\n\nfunction useAdminPortalSsoConnectionContext() {\n const context = React.useContext(AdminPortalSsoConnectionContext);\n if (!context) {\n throw new Error(\n \"useAdminPortalSsoConnectionContext must be used within a AdminPortalSsoConnectionContext provider\",\n );\n }\n return context;\n}\n\nconst AdminPortalSsoConnection: React.FC<AdminPortalSsoConnectionProps> = ({\n currentDate,\n connectionStatus,\n identityProvider,\n expiryDate,\n lastSession,\n adminPortalOpenButton,\n ...domProps\n}) => {\n return (\n <CardList.Root size=\"2\" {...getWidgetRootDomProps(\"resolved\", domProps)}>\n <AdminPortalSsoConnectionContext.Provider value={{ connectionStatus }}>\n <CardList.Item>\n <Flex direction=\"row\" justify=\"between\" align=\"center\" gap=\"2\">\n {(() => {\n if (connectionStatus === \"NotConfigured\") {\n return (\n <>\n <Text size=\"2\" color=\"gray\">\n <Translation\n defaultMessage=\"You haven't set up Single Sign-On yet.\"\n id=\"KDs1Ib\"\n description=\"Empty state message when SSO is not configured\"\n />\n </Text>\n {adminPortalOpenButton}\n </>\n );\n }\n\n return (\n <>\n <SessionInfo\n connectionStatus={connectionStatus}\n identityProvider={identityProvider}\n lastSession={lastSession}\n currentDate={currentDate}\n />\n <Flex gap=\"5\" align=\"center\">\n <SsoStatus status={connectionStatus} />\n {adminPortalOpenButton}\n </Flex>\n </>\n );\n })()}\n </Flex>\n </CardList.Item>\n {connectionStatus === \"Expired\" && (\n <CardList.Item>\n <Flex align=\"start\" gap=\"2\">\n <Box asChild mt=\"2px\" flexShrink=\"0\">\n <InfoCircledIcon color=\"gray\" />\n </Box>\n {(() => {\n if (connectionStatus === \"Expired\") {\n return (\n <Text size=\"2\" color=\"gray\">\n {(() => {\n if (!expiryDate) {\n return (\n <Translation\n defaultMessage=\"The SAML response signing certificate has expired. Users won't be able to sign-in to the application until the certificate is renewed.\"\n id=\"5tX19v\"\n description=\"Error message when SAML certificate has expired (no date)\"\n />\n );\n }\n\n return (\n <Translation\n defaultMessage=\"The SAML response signing certificate expired on {expiryDate}. Users won't be able to sign-in to the application until the certificate is renewed.\"\n id=\"vmTW/h\"\n description=\"Error message when SAML certificate has expired with date\"\n values={{\n expiryDate: (\n <Text weight=\"bold\" as=\"span\">\n {expiryDate?.toLocaleString(\"en-US\", {\n month: \"long\",\n day: \"numeric\",\n year: \"numeric\",\n })}\n </Text>\n ),\n }}\n />\n );\n })()}\n </Text>\n );\n }\n\n if (connectionStatus === \"Expiring\") {\n return (\n <Text size=\"2\" color=\"gray\">\n {(() => {\n if (!expiryDate) {\n return (\n <Translation\n defaultMessage=\"The SAML response signing certificate is expiring soon. When expired, users won't be able to sign-in.\"\n id=\"3dgA5f\"\n description=\"Warning message when SAML certificate is expiring soon (no date)\"\n />\n );\n }\n\n return (\n <Translation\n defaultMessage=\"The SAML response signing certificate will expire on {expiryDate}. When expired, users won't be able to sign-in.\"\n id=\"xT9Exy\"\n description=\"Warning message when SAML certificate is expiring with date\"\n values={{\n expiryDate: (\n <Text weight=\"bold\" as=\"span\">\n {expiryDate?.toLocaleString(\"en-US\", {\n month: \"long\",\n day: \"numeric\",\n year: \"numeric\",\n })}\n </Text>\n ),\n }}\n />\n );\n })()}\n </Text>\n );\n }\n })()}\n </Flex>\n </CardList.Item>\n )}\n </AdminPortalSsoConnectionContext.Provider>\n </CardList.Root>\n );\n};\n\nfunction SsoStatus({\n status,\n}: {\n status: AdminPortalSsoConnectionStatusProps[\"connectionStatus\"];\n}) {\n if (status === \"NotConfigured\") {\n return null;\n }\n\n if (status === \"Inactive\") {\n return (\n <Status state=\"waiting\">\n <Translation\n defaultMessage=\"Setup in progress\"\n id=\"MQR5mR\"\n description=\"Status label when SSO setup is incomplete\"\n />\n </Status>\n );\n }\n\n if (status === \"Expired\") {\n return (\n <Status state=\"error\">\n <Translation\n defaultMessage=\"Requires action\"\n id=\"Yo2vHC\"\n description=\"Status label when SSO requires attention\"\n />\n </Status>\n );\n }\n\n if (status === \"Active\" || status === \"Expiring\") {\n return (\n <Status state=\"success\">\n <Translation\n defaultMessage=\"Connected\"\n id=\"8S+Cyw\"\n description=\"Status label when SSO is active\"\n />\n </Status>\n );\n }\n\n return unreachable(status);\n}\n\nfunction SessionInfo({\n currentDate,\n identityProvider,\n lastSession,\n connectionStatus,\n}: {\n identityProvider: IdentityProvider;\n lastSession: Date | null;\n currentDate: Date | null;\n connectionStatus: AdminPortalSsoConnectionStatusProps[\"connectionStatus\"];\n}) {\n const relativeTimeString = React.useMemo(() => {\n if (\n !lastSession ||\n !currentDate ||\n connectionStatus === \"NotConfigured\" ||\n connectionStatus === \"Inactive\"\n ) {\n return null;\n }\n\n return getRelativeTimeString(currentDate, lastSession);\n }, [lastSession, currentDate, connectionStatus]);\n\n return (\n <Flex gap=\"4\" align=\"center\">\n <IconPanel color=\"panel\">\n <ProviderIcon provider={identityProvider} size=\"2\" />\n </IconPanel>\n {lastSession ? (\n <Flex direction=\"column\">\n <Text size=\"2\" weight=\"bold\">\n {getIdentityProviderName(identityProvider)}\n </Text>\n {relativeTimeString ? (\n <Text color=\"gray\" size=\"2\">\n <Translation\n defaultMessage=\"Last session {relativeTime}\"\n id=\"yN72Gc\"\n description=\"Label showing when the last SSO session occurred\"\n values={{ relativeTime: relativeTimeString }}\n />\n </Text>\n ) : null}\n </Flex>\n ) : (\n <Text size=\"2\" weight=\"bold\">\n {getIdentityProviderName(identityProvider)}\n </Text>\n )}\n </Flex>\n );\n}\n\nfunction AdminPortalOpenButton({\n isPending,\n initConfig,\n}: {\n isPending: boolean;\n initConfig: () => void;\n}) {\n const { connectionStatus } = useAdminPortalSsoConnectionContext();\n const label = (() => {\n switch (connectionStatus) {\n case \"NotConfigured\":\n return (\n <Translation\n defaultMessage=\"Set up SSO\"\n id=\"MtkNQO\"\n description=\"Button label to start SSO setup\"\n />\n );\n case \"Inactive\":\n return (\n <Translation\n defaultMessage=\"Continue setup\"\n id=\"HFxrbY\"\n description=\"Button label to continue incomplete SSO setup\"\n />\n );\n case \"Active\":\n case \"Expiring\":\n case \"Expired\":\n return (\n <Translation\n defaultMessage=\"Manage\"\n id=\"T1VKzP\"\n description=\"Button label to manage SSO settings\"\n />\n );\n default:\n return unreachable(connectionStatus);\n }\n })();\n\n return (\n <Button\n variant=\"secondary\"\n loading={isPending}\n disabled={isPending}\n onClick={initConfig}\n >\n {label} <ExternalLinkIcon aria-hidden />\n </Button>\n );\n}\n\ninterface AdminPortalSsoConnectionLoadingProps extends WidgetRootDomProps {}\n\nconst AdminPortalSsoConnectionLoading: React.FC<\n AdminPortalSsoConnectionLoadingProps\n> = (props) => {\n return (\n <Card size=\"2\" {...getWidgetRootDomProps(\"loading\", props)}>\n <Flex direction=\"row\" justify=\"between\" align=\"center\" gap=\"2\">\n <Flex gap=\"4\" align=\"center\">\n <Skeleton>\n <IconPanel color=\"panel\">\n <ProviderIcon provider=\"okta\" size=\"2\" />\n </IconPanel>\n </Skeleton>\n <Flex direction=\"column\" gap=\"1\" my=\"-4px\">\n <Skeleton>\n {/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */}\n <Text size=\"1\">Okta</Text>\n </Skeleton>\n <Skeleton>\n {/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */}\n <Text size=\"1\">Last session 10 minutes ago</Text>\n </Skeleton>\n </Flex>\n </Flex>\n <Flex gap=\"5\" align=\"center\">\n <Skeleton>\n {/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */}\n <Status state=\"error\">Requires action</Status>\n </Skeleton>\n <Skeleton>\n {/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */}\n <Button variant=\"secondary\">\n Manage <ExternalLinkIcon aria-hidden />\n </Button>\n </Skeleton>\n </Flex>\n </Flex>\n </Card>\n );\n};\n\ninterface AdminPortalSsoConnectionErrorProps extends WidgetRootDomProps {\n error: unknown;\n}\n\nconst AdminPortalSsoConnectionError: React.FC<\n AdminPortalSsoConnectionErrorProps\n> = ({ error, ...domProps }) => {\n const translate = useTranslation();\n React.useEffect(() => {\n console.error(error);\n }, [error]);\n\n const { heading, message } = getErrorMessage(error, translate);\n\n return (\n <Card size=\"2\" {...getWidgetRootDomProps(\"error\", domProps)}>\n <Flex direction=\"row\" justify=\"between\" align=\"center\" gap=\"2\">\n <Flex gap=\"4\" align=\"center\">\n <Flex\n align=\"center\"\n justify=\"center\"\n width=\"24px\"\n height=\"24px\"\n style={{\n borderRadius: \"9999px\",\n backgroundColor: \"var(--red-a4)\",\n color: \"var(--red-a11)\",\n flexShrink: 0,\n }}\n >\n <Cross2Icon width=\"18px\" height=\"18px\" />\n </Flex>\n <Flex direction=\"column\">\n <Text size=\"2\" weight=\"bold\">\n {heading}\n </Text>\n <Text size=\"2\" color=\"gray\">\n {message}\n </Text>\n </Flex>\n </Flex>\n </Flex>\n </Card>\n );\n};\n\nfunction getRelativeTimeString(\n currentDate: Date | null,\n lastSession: Date | null,\n) {\n if (!currentDate || !lastSession) {\n return null;\n }\n\n const rtf = new Intl.RelativeTimeFormat(\"en\", { numeric: \"auto\" });\n const diff = lastSession.getTime() - currentDate.getTime();\n\n const diffSeconds = Math.round(diff / 1000);\n const diffMinutes = Math.round(diffSeconds / 60);\n const diffHours = Math.round(diffMinutes / 60);\n const diffDays = Math.round(diffHours / 24);\n const diffMonths = Math.round(diffDays / 30);\n const diffYears = Math.round(diffMonths / 12);\n\n if (Math.abs(diffSeconds) < 60) {\n return \"now\";\n }\n\n if (Math.abs(diffMinutes) < 60) {\n return rtf.format(diffMinutes, \"minute\");\n }\n\n if (Math.abs(diffHours) < 24) {\n return rtf.format(diffHours, \"hour\");\n }\n\n if (Math.abs(diffDays) < 30) {\n return rtf.format(diffDays, \"day\");\n }\n\n if (Math.abs(diffMonths) < 12) {\n return rtf.format(diffMonths, \"month\");\n }\n\n return rtf.format(diffYears, \"year\");\n}\n\nfunction getWidgetRootDomProps(\n state: WidgetRootState,\n domProps: WidgetRootDomProps,\n) {\n return getDomProps({\n ...domProps,\n isWidgetRoot: true,\n widgetId: \"admin-portal-sso-connection\",\n widgetState: state,\n });\n}\n\nexport type {\n AdminPortalSsoConnectionProps,\n AdminPortalSsoConnectionLoadingProps,\n AdminPortalSsoConnectionErrorProps,\n};\nexport {\n AdminPortalSsoConnection,\n AdminPortalSsoConnectionLoading,\n AdminPortalSsoConnectionError,\n /** @internal */\n AdminPortalOpenButton,\n};\n"],"mappings":"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","names":[]}
@@ -44,9 +44,8 @@ type AdminPortalSsoConnectionProps = WidgetRootDomProps & AdminPortalSsoConnecti
44
44
  adminPortalOpenButton: React.ReactNode;
45
45
  };
46
46
  declare const AdminPortalSsoConnection: React.FC<AdminPortalSsoConnectionProps>;
47
- declare function AdminPortalOpenButton({ isPending, href, initConfig, }: {
47
+ declare function AdminPortalOpenButton({ isPending, initConfig, }: {
48
48
  isPending: boolean;
49
- href: string | null;
50
49
  initConfig: () => void;
51
50
  }): react_jsx_runtime.JSX.Element;
52
51
  interface AdminPortalSsoConnectionLoadingProps extends WidgetRootDomProps {
@@ -58,7 +58,7 @@ const ApiKeysContextProvider = ({ children }) => {
58
58
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ApiKeysContext.Provider, { value: context, children });
59
59
  };
60
60
  const NOOP = () => void 0;
61
- const EMPTY_PAGINATION = {};
61
+ const EMPTY_PAGINATION = { before: null, after: null };
62
62
  function useApiKeysContext(initialContext) {
63
63
  const context = React.useContext(ApiKeysContext);
64
64
  if (context) {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/lib/api-keys/api-keys-context.tsx"],"sourcesContent":["\"use client\";\n\nimport * as React from \"react\";\nimport {\n ApiKeysAction,\n ApiKeysState,\n useApiKeysState,\n} from \"./api-keys-state.js\";\nimport { ListMetadata } from \"../../api/endpoint.js\";\n\nexport interface ApiKeysContextType {\n state: ApiKeysState;\n dispatch: React.Dispatch<ApiKeysAction>;\n}\n\nconst ApiKeysContext = React.createContext<ApiKeysContextType | undefined>(\n undefined,\n);\nApiKeysContext.displayName = \"ApiKeysContext\";\n\nconst initialState: ApiKeysState = {\n pagination: null,\n searchQuery: null,\n createDialogOpen: false,\n createdApiKey: null,\n};\n\nexport const ApiKeysContextProvider: React.FC<{\n children?: React.ReactNode;\n}> = ({ children }) => {\n const [state, dispatch] = useApiKeysState(initialState);\n\n const context = React.useMemo<ApiKeysContextType>(\n () => ({\n state,\n dispatch,\n }),\n [state, dispatch],\n );\n\n return (\n <ApiKeysContext.Provider value={context}>\n {children}\n </ApiKeysContext.Provider>\n );\n};\n\nconst NOOP = () => void 0;\nconst EMPTY_PAGINATION: ListMetadata = {};\n\n/**\n * The context may be provided if it is instantiated in the tree above the user.\n */\nexport function useApiKeysContext(\n initialContext?: ApiKeysContextType | null,\n): ApiKeysContextType {\n const context = React.useContext(ApiKeysContext);\n\n if (context) {\n return context;\n }\n\n if (initialContext) {\n return initialContext;\n }\n\n return {\n dispatch: NOOP,\n state: {\n pagination: EMPTY_PAGINATION,\n searchQuery: null,\n createDialogOpen: false,\n createdApiKey: null,\n },\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAyCI;AAvCJ,YAAuB;AACvB,4BAIO;AAQP,MAAM,iBAAiB,MAAM;AAAA,EAC3B;AACF;AACA,eAAe,cAAc;AAE7B,MAAM,eAA6B;AAAA,EACjC,YAAY;AAAA,EACZ,aAAa;AAAA,EACb,kBAAkB;AAAA,EAClB,eAAe;AACjB;AAEO,MAAM,yBAER,CAAC,EAAE,SAAS,MAAM;AACrB,QAAM,CAAC,OAAO,QAAQ,QAAI,uCAAgB,YAAY;AAEtD,QAAM,UAAU,MAAM;AAAA,IACpB,OAAO;AAAA,MACL;AAAA,MACA;AAAA,IACF;AAAA,IACA,CAAC,OAAO,QAAQ;AAAA,EAClB;AAEA,SACE,4CAAC,eAAe,UAAf,EAAwB,OAAO,SAC7B,UACH;AAEJ;AAEA,MAAM,OAAO,MAAM;AACnB,MAAM,mBAAiC,CAAC;AAKjC,SAAS,kBACd,gBACoB;AACpB,QAAM,UAAU,MAAM,WAAW,cAAc;AAE/C,MAAI,SAAS;AACX,WAAO;AAAA,EACT;AAEA,MAAI,gBAAgB;AAClB,WAAO;AAAA,EACT;AAEA,SAAO;AAAA,IACL,UAAU;AAAA,IACV,OAAO;AAAA,MACL,YAAY;AAAA,MACZ,aAAa;AAAA,MACb,kBAAkB;AAAA,MAClB,eAAe;AAAA,IACjB;AAAA,EACF;AACF;","names":[]}
1
+ {"version":3,"sources":["../../../../src/lib/api-keys/api-keys-context.tsx"],"sourcesContent":["\"use client\";\n\nimport * as React from \"react\";\nimport {\n ApiKeysAction,\n ApiKeysState,\n useApiKeysState,\n} from \"./api-keys-state.js\";\nimport { ListMetadata } from \"../../api/endpoint.js\";\n\nexport interface ApiKeysContextType {\n state: ApiKeysState;\n dispatch: React.Dispatch<ApiKeysAction>;\n}\n\nconst ApiKeysContext = React.createContext<ApiKeysContextType | undefined>(\n undefined,\n);\nApiKeysContext.displayName = \"ApiKeysContext\";\n\nconst initialState: ApiKeysState = {\n pagination: null,\n searchQuery: null,\n createDialogOpen: false,\n createdApiKey: null,\n};\n\nexport const ApiKeysContextProvider: React.FC<{\n children?: React.ReactNode;\n}> = ({ children }) => {\n const [state, dispatch] = useApiKeysState(initialState);\n\n const context = React.useMemo<ApiKeysContextType>(\n () => ({\n state,\n dispatch,\n }),\n [state, dispatch],\n );\n\n return (\n <ApiKeysContext.Provider value={context}>\n {children}\n </ApiKeysContext.Provider>\n );\n};\n\nconst NOOP = () => void 0;\nconst EMPTY_PAGINATION: ListMetadata = { before: null, after: null };\n\n/**\n * The context may be provided if it is instantiated in the tree above the user.\n */\nexport function useApiKeysContext(\n initialContext?: ApiKeysContextType | null,\n): ApiKeysContextType {\n const context = React.useContext(ApiKeysContext);\n\n if (context) {\n return context;\n }\n\n if (initialContext) {\n return initialContext;\n }\n\n return {\n dispatch: NOOP,\n state: {\n pagination: EMPTY_PAGINATION,\n searchQuery: null,\n createDialogOpen: false,\n createdApiKey: null,\n },\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAyCI;AAvCJ,YAAuB;AACvB,4BAIO;AAQP,MAAM,iBAAiB,MAAM;AAAA,EAC3B;AACF;AACA,eAAe,cAAc;AAE7B,MAAM,eAA6B;AAAA,EACjC,YAAY;AAAA,EACZ,aAAa;AAAA,EACb,kBAAkB;AAAA,EAClB,eAAe;AACjB;AAEO,MAAM,yBAER,CAAC,EAAE,SAAS,MAAM;AACrB,QAAM,CAAC,OAAO,QAAQ,QAAI,uCAAgB,YAAY;AAEtD,QAAM,UAAU,MAAM;AAAA,IACpB,OAAO;AAAA,MACL;AAAA,MACA;AAAA,IACF;AAAA,IACA,CAAC,OAAO,QAAQ;AAAA,EAClB;AAEA,SACE,4CAAC,eAAe,UAAf,EAAwB,OAAO,SAC7B,UACH;AAEJ;AAEA,MAAM,OAAO,MAAM;AACnB,MAAM,mBAAiC,EAAE,QAAQ,MAAM,OAAO,KAAK;AAK5D,SAAS,kBACd,gBACoB;AACpB,QAAM,UAAU,MAAM,WAAW,cAAc;AAE/C,MAAI,SAAS;AACX,WAAO;AAAA,EACT;AAEA,MAAI,gBAAgB;AAClB,WAAO;AAAA,EACT;AAEA,SAAO;AAAA,IACL,UAAU;AAAA,IACV,OAAO;AAAA,MACL,YAAY;AAAA,MACZ,aAAa;AAAA,MACb,kBAAkB;AAAA,MAClB,eAAe;AAAA,IACjB;AAAA,EACF;AACF;","names":[]}
@@ -37,6 +37,7 @@ var import_api_keys_search = require("./api-keys-search.js");
37
37
  var import_translation = require("../i18n/translation.js");
38
38
  var import_use_translation = require("../i18n/use-translation.js");
39
39
  var import_use_locale = require("../i18n/use-locale.js");
40
+ var import_utils = require("../utils.js");
40
41
  function NoApiKeys() {
41
42
  const { clearSearch } = (0, import_api_keys_search_provider.useApiKeysSearchContext)();
42
43
  return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_themes.Flex, { p: "6", gap: "4", justify: "center", align: "center", direction: "column", children: [
@@ -165,9 +166,10 @@ function ApiKeysTable({
165
166
  apiKeys
166
167
  }) {
167
168
  const { dispatch } = (0, import_api_keys_context.useApiKeysContext)();
168
- const hasPagination = apiKeys.listMetadata.before || apiKeys.listMetadata.after;
169
- const hasPreviousPage = apiKeys.listMetadata.after;
170
- const hasNextPage = apiKeys.listMetadata.before;
169
+ const pagination = (0, import_utils.getListMetadata)(apiKeys);
170
+ const hasPagination = !!(pagination.before || pagination.after);
171
+ const hasPreviousPage = !!pagination.after;
172
+ const hasNextPage = !!pagination.before;
171
173
  return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_themes.Flex, { direction: "column", align: "stretch", gap: "3", children: [
172
174
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ApiKeysTableHeader, {}),
173
175
  apiKeys.data.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(NoApiKeys, {}) : /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
@@ -218,7 +220,7 @@ function ApiKeysTable({
218
220
  size: "1",
219
221
  onClick: () => dispatch({
220
222
  type: "SET_PAGINATION",
221
- pagination: { after: apiKeys.listMetadata.after }
223
+ pagination
222
224
  }),
223
225
  children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
224
226
  import_translation.Translation,
@@ -238,7 +240,7 @@ function ApiKeysTable({
238
240
  size: "1",
239
241
  onClick: () => dispatch({
240
242
  type: "SET_PAGINATION",
241
- pagination: { before: apiKeys.listMetadata.before }
243
+ pagination
242
244
  }),
243
245
  children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
244
246
  import_translation.Translation,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/lib/api-keys/api-keys-table.tsx"],"sourcesContent":["import { Flex, Text, Table, Code, Heading } from \"@radix-ui/themes\";\nimport { Button, DropdownMenu, IconButton } from \"../elements.js\";\nimport { DotsHorizontalIcon, MagnifyingGlassIcon } from \"@radix-ui/react-icons\";\nimport { useState } from \"react\";\nimport { RevokeApiKeyDialog } from \"./revoke-api-key-dialog.js\";\nimport { CreateApiKeyButton } from \"./create-api-key.js\";\nimport { ApiKeyDetailsDialog } from \"./api-key-details-dialog.js\";\nimport { useIsHydrated } from \"../use-is-hydrated.js\";\nimport { RelativeTime } from \"./relative-time.js\";\nimport {\n ListOrganizationApiKeysResponse,\n ListOrganizationApiKeysResponseData,\n} from \"../../api/endpoint.js\";\nimport { useApiKeysContext } from \"./api-keys-context.js\";\nimport { useApiKeysSearchContext } from \"./api-keys-search-provider.js\";\nimport { ApiKeysSearch } from \"./api-keys-search.js\";\nimport { Translation } from \"../i18n/translation.js\";\nimport { useTranslation } from \"../i18n/use-translation.js\";\nimport { useLocale } from \"../i18n/use-locale.js\";\n\nfunction NoApiKeys() {\n const { clearSearch } = useApiKeysSearchContext();\n return (\n <Flex p=\"6\" gap=\"4\" justify=\"center\" align=\"center\" direction=\"column\">\n <Flex direction=\"column\" gap=\"1\" maxWidth=\"420px\" align=\"center\">\n <MagnifyingGlassIcon\n style={{ color: \"var(--gray-9)\" }}\n width=\"32px\"\n height=\"32px\"\n />\n <Heading size=\"5\" mb=\"1\" wrap=\"balance\" as=\"h3\">\n <Translation\n defaultMessage=\"No API keys match your search\"\n id=\"cKitHb\"\n description=\"Empty state message when no API keys match search\"\n />\n </Heading>\n </Flex>\n\n <Button variant=\"secondary\" onClick={clearSearch}>\n <Translation\n defaultMessage=\"Clear search\"\n id=\"jTupOW\"\n description=\"Button to clear API key search filters\"\n />\n </Button>\n </Flex>\n );\n}\n\nfunction ApiKeysTableHeader() {\n return (\n <Flex justify=\"between\" align=\"center\">\n <ApiKeysSearch name=\"api-keys-widget-search\" style={{ width: \"390px\" }} />\n <CreateApiKeyButton />\n </Flex>\n );\n}\n\nfunction CreatedOn({ createdOn }: { createdOn: Date }) {\n const isHydrated = useIsHydrated();\n const locale = useLocale();\n return (\n <>\n {createdOn.toLocaleDateString(locale, {\n timeZone: isHydrated ? undefined : \"UTC\",\n month: \"short\",\n day: \"numeric\",\n year: \"numeric\",\n })}\n </>\n );\n}\n\ninterface ApiKeyRowProps {\n apiKey: ListOrganizationApiKeysResponseData;\n}\n\nfunction ApiKeyRow({ apiKey }: ApiKeyRowProps) {\n const [revokeDialogOpen, setRevokeDialogOpen] = useState(false);\n const [detailsOpen, setDetailsOpen] = useState(false);\n const translate = useTranslation();\n return (\n <>\n <RevokeApiKeyDialog\n // always remount the form when the dialog is opened to reset the validation errors\n key={`${revokeDialogOpen}`}\n open={revokeDialogOpen}\n onOpenChange={setRevokeDialogOpen}\n apiKey={apiKey}\n />\n <ApiKeyDetailsDialog\n open={detailsOpen}\n onOpenChange={setDetailsOpen}\n apiKey={apiKey}\n permissions={apiKey.permissions}\n />\n <Table.Row align=\"center\">\n <Table.Cell>\n <Text>{apiKey.name}</Text>\n </Table.Cell>\n <Table.Cell>\n <Code color=\"gray\">{apiKey.obfuscatedValue}</Code>\n </Table.Cell>\n <Table.Cell>\n <Text\n style={apiKey.lastUsedAt ? undefined : { color: \"var(--gray-10)\" }}\n >\n <RelativeTime\n date={apiKey.lastUsedAt ? new Date(apiKey.lastUsedAt) : undefined}\n />\n </Text>\n </Table.Cell>\n <Table.Cell>\n <Text>\n <CreatedOn createdOn={new Date(apiKey.createdAt)} />\n </Text>\n </Table.Cell>\n <Table.Cell justify=\"end\">\n <DropdownMenu.Root>\n <DropdownMenu.Trigger>\n {(() => {\n const title = translate({\n defaultMessage: \"API key actions\",\n id: \"RIBfYe\",\n description: \"Tooltip for API key actions menu button\",\n });\n return (\n <IconButton title={title}>\n <DotsHorizontalIcon />\n </IconButton>\n );\n })()}\n </DropdownMenu.Trigger>\n <DropdownMenu.Content size=\"2\" align=\"end\">\n <DropdownMenu.Item onSelect={() => setDetailsOpen(true)}>\n <Translation\n defaultMessage=\"View details\"\n id=\"VGKbbj\"\n description=\"Menu item to view API key details\"\n />\n </DropdownMenu.Item>\n <DropdownMenu.Item\n variant=\"destructive\"\n onSelect={() => setRevokeDialogOpen(true)}\n >\n <Translation\n defaultMessage=\"Revoke key\"\n id=\"KZIJPP\"\n description=\"Menu item to revoke an API key\"\n />\n </DropdownMenu.Item>\n </DropdownMenu.Content>\n </DropdownMenu.Root>\n </Table.Cell>\n </Table.Row>\n </>\n );\n}\n\nexport function ApiKeysTable({\n apiKeys,\n}: {\n apiKeys: ListOrganizationApiKeysResponse;\n}) {\n const { dispatch } = useApiKeysContext();\n const hasPagination =\n apiKeys.listMetadata.before || apiKeys.listMetadata.after;\n const hasPreviousPage = apiKeys.listMetadata.after;\n const hasNextPage = apiKeys.listMetadata.before;\n\n return (\n <Flex direction=\"column\" align=\"stretch\" gap=\"3\">\n <ApiKeysTableHeader />\n {apiKeys.data.length === 0 ? (\n <NoApiKeys />\n ) : (\n <>\n <Table.Root variant=\"ghost\" size=\"2\">\n <Table.Header>\n <Table.Row>\n <Table.ColumnHeaderCell width=\"25%\">\n <Translation\n defaultMessage=\"Name\"\n id=\"VYbVXN\"\n description=\"Table column header for API key name\"\n />\n </Table.ColumnHeaderCell>\n <Table.ColumnHeaderCell width=\"25%\">\n <Translation\n defaultMessage=\"Secret key\"\n id=\"H5k7GB\"\n description=\"Table column header for API key secret value\"\n />\n </Table.ColumnHeaderCell>\n <Table.ColumnHeaderCell width=\"25%\">\n <Translation\n defaultMessage=\"Last used\"\n id=\"E46t3O\"\n description=\"Table column header for API key last used timestamp\"\n />\n </Table.ColumnHeaderCell>\n <Table.ColumnHeaderCell width=\"25%\">\n <Translation\n defaultMessage=\"Created\"\n id=\"CXHhXd\"\n description=\"Table column header for API key creation date\"\n />\n </Table.ColumnHeaderCell>\n <Table.ColumnHeaderCell width=\"28px\" />\n </Table.Row>\n </Table.Header>\n <Table.Body>\n {apiKeys.data.map((apiKey) => (\n <ApiKeyRow key={apiKey.id} apiKey={apiKey} />\n ))}\n </Table.Body>\n </Table.Root>\n {hasPagination && (\n <Flex gap=\"2\" justify=\"end\">\n <Button\n variant=\"secondary\"\n disabled={!hasPreviousPage}\n size=\"1\"\n onClick={() =>\n dispatch({\n type: \"SET_PAGINATION\",\n pagination: { after: apiKeys.listMetadata.after },\n })\n }\n >\n <Translation\n defaultMessage=\"Previous\"\n id=\"f7TUj0\"\n description=\"Button to navigate to previous page of API keys\"\n />\n </Button>\n <Button\n variant=\"secondary\"\n disabled={!hasNextPage}\n size=\"1\"\n onClick={() =>\n dispatch({\n type: \"SET_PAGINATION\",\n pagination: { before: apiKeys.listMetadata.before },\n })\n }\n >\n <Translation\n defaultMessage=\"Next\"\n id=\"L2EBxV\"\n description=\"Button to navigate to next page of API keys\"\n />\n </Button>\n </Flex>\n )}\n </>\n )}\n </Flex>\n );\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../../../src/lib/api-keys/api-keys-table.tsx"],"sourcesContent":["import { Flex, Text, Table, Code, Heading } from \"@radix-ui/themes\";\nimport { Button, DropdownMenu, IconButton } from \"../elements.js\";\nimport { DotsHorizontalIcon, MagnifyingGlassIcon } from \"@radix-ui/react-icons\";\nimport { useState } from \"react\";\nimport { RevokeApiKeyDialog } from \"./revoke-api-key-dialog.js\";\nimport { CreateApiKeyButton } from \"./create-api-key.js\";\nimport { ApiKeyDetailsDialog } from \"./api-key-details-dialog.js\";\nimport { useIsHydrated } from \"../use-is-hydrated.js\";\nimport { RelativeTime } from \"./relative-time.js\";\nimport {\n ListOrganizationApiKeysResponse,\n ListOrganizationApiKeysResponseData,\n} from \"../../api/endpoint.js\";\nimport { useApiKeysContext } from \"./api-keys-context.js\";\nimport { useApiKeysSearchContext } from \"./api-keys-search-provider.js\";\nimport { ApiKeysSearch } from \"./api-keys-search.js\";\nimport { Translation } from \"../i18n/translation.js\";\nimport { useTranslation } from \"../i18n/use-translation.js\";\nimport { useLocale } from \"../i18n/use-locale.js\";\nimport { getListMetadata } from \"../utils.js\";\n\nfunction NoApiKeys() {\n const { clearSearch } = useApiKeysSearchContext();\n return (\n <Flex p=\"6\" gap=\"4\" justify=\"center\" align=\"center\" direction=\"column\">\n <Flex direction=\"column\" gap=\"1\" maxWidth=\"420px\" align=\"center\">\n <MagnifyingGlassIcon\n style={{ color: \"var(--gray-9)\" }}\n width=\"32px\"\n height=\"32px\"\n />\n <Heading size=\"5\" mb=\"1\" wrap=\"balance\" as=\"h3\">\n <Translation\n defaultMessage=\"No API keys match your search\"\n id=\"cKitHb\"\n description=\"Empty state message when no API keys match search\"\n />\n </Heading>\n </Flex>\n\n <Button variant=\"secondary\" onClick={clearSearch}>\n <Translation\n defaultMessage=\"Clear search\"\n id=\"jTupOW\"\n description=\"Button to clear API key search filters\"\n />\n </Button>\n </Flex>\n );\n}\n\nfunction ApiKeysTableHeader() {\n return (\n <Flex justify=\"between\" align=\"center\">\n <ApiKeysSearch name=\"api-keys-widget-search\" style={{ width: \"390px\" }} />\n <CreateApiKeyButton />\n </Flex>\n );\n}\n\nfunction CreatedOn({ createdOn }: { createdOn: Date }) {\n const isHydrated = useIsHydrated();\n const locale = useLocale();\n return (\n <>\n {createdOn.toLocaleDateString(locale, {\n timeZone: isHydrated ? undefined : \"UTC\",\n month: \"short\",\n day: \"numeric\",\n year: \"numeric\",\n })}\n </>\n );\n}\n\ninterface ApiKeyRowProps {\n apiKey: ListOrganizationApiKeysResponseData;\n}\n\nfunction ApiKeyRow({ apiKey }: ApiKeyRowProps) {\n const [revokeDialogOpen, setRevokeDialogOpen] = useState(false);\n const [detailsOpen, setDetailsOpen] = useState(false);\n const translate = useTranslation();\n return (\n <>\n <RevokeApiKeyDialog\n // always remount the form when the dialog is opened to reset the validation errors\n key={`${revokeDialogOpen}`}\n open={revokeDialogOpen}\n onOpenChange={setRevokeDialogOpen}\n apiKey={apiKey}\n />\n <ApiKeyDetailsDialog\n open={detailsOpen}\n onOpenChange={setDetailsOpen}\n apiKey={apiKey}\n permissions={apiKey.permissions}\n />\n <Table.Row align=\"center\">\n <Table.Cell>\n <Text>{apiKey.name}</Text>\n </Table.Cell>\n <Table.Cell>\n <Code color=\"gray\">{apiKey.obfuscatedValue}</Code>\n </Table.Cell>\n <Table.Cell>\n <Text\n style={apiKey.lastUsedAt ? undefined : { color: \"var(--gray-10)\" }}\n >\n <RelativeTime\n date={apiKey.lastUsedAt ? new Date(apiKey.lastUsedAt) : undefined}\n />\n </Text>\n </Table.Cell>\n <Table.Cell>\n <Text>\n <CreatedOn createdOn={new Date(apiKey.createdAt)} />\n </Text>\n </Table.Cell>\n <Table.Cell justify=\"end\">\n <DropdownMenu.Root>\n <DropdownMenu.Trigger>\n {(() => {\n const title = translate({\n defaultMessage: \"API key actions\",\n id: \"RIBfYe\",\n description: \"Tooltip for API key actions menu button\",\n });\n return (\n <IconButton title={title}>\n <DotsHorizontalIcon />\n </IconButton>\n );\n })()}\n </DropdownMenu.Trigger>\n <DropdownMenu.Content size=\"2\" align=\"end\">\n <DropdownMenu.Item onSelect={() => setDetailsOpen(true)}>\n <Translation\n defaultMessage=\"View details\"\n id=\"VGKbbj\"\n description=\"Menu item to view API key details\"\n />\n </DropdownMenu.Item>\n <DropdownMenu.Item\n variant=\"destructive\"\n onSelect={() => setRevokeDialogOpen(true)}\n >\n <Translation\n defaultMessage=\"Revoke key\"\n id=\"KZIJPP\"\n description=\"Menu item to revoke an API key\"\n />\n </DropdownMenu.Item>\n </DropdownMenu.Content>\n </DropdownMenu.Root>\n </Table.Cell>\n </Table.Row>\n </>\n );\n}\n\nexport function ApiKeysTable({\n apiKeys,\n}: {\n apiKeys: ListOrganizationApiKeysResponse;\n}) {\n const { dispatch } = useApiKeysContext();\n\n // The API response previously returned an object with the `listMetadata`\n // property. We might not need this, but it's a defensive check until we\n // verify the API response changes are correct.\n const pagination = getListMetadata(apiKeys);\n\n const hasPagination = !!(pagination.before || pagination.after);\n const hasPreviousPage = !!pagination.after;\n const hasNextPage = !!pagination.before;\n\n return (\n <Flex direction=\"column\" align=\"stretch\" gap=\"3\">\n <ApiKeysTableHeader />\n {apiKeys.data.length === 0 ? (\n <NoApiKeys />\n ) : (\n <>\n <Table.Root variant=\"ghost\" size=\"2\">\n <Table.Header>\n <Table.Row>\n <Table.ColumnHeaderCell width=\"25%\">\n <Translation\n defaultMessage=\"Name\"\n id=\"VYbVXN\"\n description=\"Table column header for API key name\"\n />\n </Table.ColumnHeaderCell>\n <Table.ColumnHeaderCell width=\"25%\">\n <Translation\n defaultMessage=\"Secret key\"\n id=\"H5k7GB\"\n description=\"Table column header for API key secret value\"\n />\n </Table.ColumnHeaderCell>\n <Table.ColumnHeaderCell width=\"25%\">\n <Translation\n defaultMessage=\"Last used\"\n id=\"E46t3O\"\n description=\"Table column header for API key last used timestamp\"\n />\n </Table.ColumnHeaderCell>\n <Table.ColumnHeaderCell width=\"25%\">\n <Translation\n defaultMessage=\"Created\"\n id=\"CXHhXd\"\n description=\"Table column header for API key creation date\"\n />\n </Table.ColumnHeaderCell>\n <Table.ColumnHeaderCell width=\"28px\" />\n </Table.Row>\n </Table.Header>\n <Table.Body>\n {apiKeys.data.map((apiKey) => (\n <ApiKeyRow key={apiKey.id} apiKey={apiKey} />\n ))}\n </Table.Body>\n </Table.Root>\n {hasPagination && (\n <Flex gap=\"2\" justify=\"end\">\n <Button\n variant=\"secondary\"\n disabled={!hasPreviousPage}\n size=\"1\"\n onClick={() =>\n dispatch({\n type: \"SET_PAGINATION\",\n pagination,\n })\n }\n >\n <Translation\n defaultMessage=\"Previous\"\n id=\"f7TUj0\"\n description=\"Button to navigate to previous page of API keys\"\n />\n </Button>\n <Button\n variant=\"secondary\"\n disabled={!hasNextPage}\n size=\"1\"\n onClick={() =>\n dispatch({\n type: \"SET_PAGINATION\",\n pagination,\n })\n }\n >\n <Translation\n defaultMessage=\"Next\"\n id=\"L2EBxV\"\n description=\"Button to navigate to next page of API keys\"\n />\n </Button>\n </Flex>\n )}\n </>\n )}\n </Flex>\n );\n}\n"],"mappings":"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","names":[]}