@workos-inc/widgets 1.7.1 → 1.8.0

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 (215) hide show
  1. package/CHANGELOG.md +9 -0
  2. package/dist/cjs/api/endpoint.cjs +1 -0
  3. package/dist/cjs/api/endpoint.cjs.map +1 -1
  4. package/dist/cjs/api/endpoint.d.cts +1 -0
  5. package/dist/cjs/index.cjs +5 -2
  6. package/dist/cjs/index.cjs.map +1 -1
  7. package/dist/cjs/index.d.cts +1 -0
  8. package/dist/cjs/lib/add-mfa-dialog.cjs +133 -61
  9. package/dist/cjs/lib/add-mfa-dialog.cjs.map +1 -1
  10. package/dist/cjs/lib/admin-portal-domain-verification.cjs +41 -5
  11. package/dist/cjs/lib/admin-portal-domain-verification.cjs.map +1 -1
  12. package/dist/cjs/lib/admin-portal-sso-connection.cjs +121 -44
  13. package/dist/cjs/lib/admin-portal-sso-connection.cjs.map +1 -1
  14. package/dist/cjs/lib/api-keys/api-key-details-card.cjs +25 -3
  15. package/dist/cjs/lib/api-keys/api-key-details-card.cjs.map +1 -1
  16. package/dist/cjs/lib/api-keys/api-key-details-dialog.cjs +25 -3
  17. package/dist/cjs/lib/api-keys/api-key-details-dialog.cjs.map +1 -1
  18. package/dist/cjs/lib/api-keys/api-keys-search.cjs +13 -4
  19. package/dist/cjs/lib/api-keys/api-keys-search.cjs.map +1 -1
  20. package/dist/cjs/lib/api-keys/api-keys-table.cjs +94 -12
  21. package/dist/cjs/lib/api-keys/api-keys-table.cjs.map +1 -1
  22. package/dist/cjs/lib/api-keys/api-keys.cjs +16 -2
  23. package/dist/cjs/lib/api-keys/api-keys.cjs.map +1 -1
  24. package/dist/cjs/lib/api-keys/create-api-key.cjs +172 -20
  25. package/dist/cjs/lib/api-keys/create-api-key.cjs.map +1 -1
  26. package/dist/cjs/lib/api-keys/relative-time.cjs +12 -2
  27. package/dist/cjs/lib/api-keys/relative-time.cjs.map +1 -1
  28. package/dist/cjs/lib/api-keys/revoke-api-key-dialog.cjs +49 -7
  29. package/dist/cjs/lib/api-keys/revoke-api-key-dialog.cjs.map +1 -1
  30. package/dist/cjs/lib/change-password-dialog.cjs +122 -16
  31. package/dist/cjs/lib/change-password-dialog.cjs.map +1 -1
  32. package/dist/cjs/lib/copy-button.cjs +14 -2
  33. package/dist/cjs/lib/copy-button.cjs.map +1 -1
  34. package/dist/cjs/lib/copy-button.d.cts +2 -1
  35. package/dist/cjs/lib/delete-domain-dialog.cjs +52 -19
  36. package/dist/cjs/lib/delete-domain-dialog.cjs.map +1 -1
  37. package/dist/cjs/lib/delete-user-dialog.cjs +46 -11
  38. package/dist/cjs/lib/delete-user-dialog.cjs.map +1 -1
  39. package/dist/cjs/lib/delete-user-dialog.d.cts +2 -2
  40. package/dist/cjs/lib/domain-actions.cjs +51 -7
  41. package/dist/cjs/lib/domain-actions.cjs.map +1 -1
  42. package/dist/cjs/lib/domain-item.cjs +42 -8
  43. package/dist/cjs/lib/domain-item.cjs.map +1 -1
  44. package/dist/cjs/lib/edit-user-profile-dialog.cjs +62 -11
  45. package/dist/cjs/lib/edit-user-profile-dialog.cjs.map +1 -1
  46. package/dist/cjs/lib/edit-user-role-dialog.cjs +90 -17
  47. package/dist/cjs/lib/edit-user-role-dialog.cjs.map +1 -1
  48. package/dist/cjs/lib/elements.cjs +14 -3
  49. package/dist/cjs/lib/elements.cjs.map +1 -1
  50. package/dist/cjs/lib/elements.d.cts +5 -2
  51. package/dist/cjs/lib/elevated-access.cjs +78 -18
  52. package/dist/cjs/lib/elevated-access.cjs.map +1 -1
  53. package/dist/cjs/lib/generic-error.cjs +53 -11
  54. package/dist/cjs/lib/generic-error.cjs.map +1 -1
  55. package/dist/cjs/lib/generic-error.d.cts +5 -1
  56. package/dist/cjs/lib/i18n/intl-context.cjs +47 -0
  57. package/dist/cjs/lib/i18n/intl-context.cjs.map +1 -0
  58. package/dist/cjs/lib/i18n/intl-context.d.cts +29 -0
  59. package/dist/cjs/lib/i18n/translation.cjs +67 -0
  60. package/dist/cjs/lib/i18n/translation.cjs.map +1 -0
  61. package/dist/cjs/lib/i18n/translation.d.cts +16 -0
  62. package/dist/cjs/lib/i18n/use-locale.cjs +33 -0
  63. package/dist/cjs/lib/i18n/use-locale.cjs.map +1 -0
  64. package/dist/cjs/lib/i18n/use-locale.d.cts +7 -0
  65. package/dist/cjs/lib/i18n/use-translation.cjs +47 -0
  66. package/dist/cjs/lib/i18n/use-translation.cjs.map +1 -0
  67. package/dist/cjs/lib/i18n/use-translation.d.cts +15 -0
  68. package/dist/cjs/lib/identity-providers.d.cts +1 -1
  69. package/dist/cjs/lib/invite-user-dialog.cjs +69 -14
  70. package/dist/cjs/lib/invite-user-dialog.cjs.map +1 -1
  71. package/dist/cjs/lib/logout-all-sessions-dialog.cjs +33 -4
  72. package/dist/cjs/lib/logout-all-sessions-dialog.cjs.map +1 -1
  73. package/dist/cjs/lib/logout-dialog.cjs +34 -10
  74. package/dist/cjs/lib/logout-dialog.cjs.map +1 -1
  75. package/dist/cjs/lib/organization-switcher.cjs +12 -2
  76. package/dist/cjs/lib/organization-switcher.cjs.map +1 -1
  77. package/dist/cjs/lib/pipes.cjs +175 -36
  78. package/dist/cjs/lib/pipes.cjs.map +1 -1
  79. package/dist/cjs/lib/resend-invite-dialog.cjs +67 -17
  80. package/dist/cjs/lib/resend-invite-dialog.cjs.map +1 -1
  81. package/dist/cjs/lib/reset-mfa-dialog.cjs +50 -7
  82. package/dist/cjs/lib/reset-mfa-dialog.cjs.map +1 -1
  83. package/dist/cjs/lib/revoke-invite-dialog.cjs +42 -10
  84. package/dist/cjs/lib/revoke-invite-dialog.cjs.map +1 -1
  85. package/dist/cjs/lib/save-button.cjs +9 -1
  86. package/dist/cjs/lib/save-button.cjs.map +1 -1
  87. package/dist/cjs/lib/set-password-dialog.cjs +101 -13
  88. package/dist/cjs/lib/set-password-dialog.cjs.map +1 -1
  89. package/dist/cjs/lib/user-actions-dropdown.cjs +54 -6
  90. package/dist/cjs/lib/user-actions-dropdown.cjs.map +1 -1
  91. package/dist/cjs/lib/user-profile.cjs +81 -10
  92. package/dist/cjs/lib/user-profile.cjs.map +1 -1
  93. package/dist/cjs/lib/user-security.cjs +127 -25
  94. package/dist/cjs/lib/user-security.cjs.map +1 -1
  95. package/dist/cjs/lib/user-sessions.cjs +74 -15
  96. package/dist/cjs/lib/user-sessions.cjs.map +1 -1
  97. package/dist/cjs/lib/users-management.cjs +265 -49
  98. package/dist/cjs/lib/users-management.cjs.map +1 -1
  99. package/dist/cjs/lib/users-search.cjs +18 -4
  100. package/dist/cjs/lib/users-search.cjs.map +1 -1
  101. package/dist/cjs/lib/utils.cjs +10 -7
  102. package/dist/cjs/lib/utils.cjs.map +1 -1
  103. package/dist/cjs/lib/utils.d.cts +2 -1
  104. package/dist/cjs/lib/view-dns-record-dialog.cjs +89 -18
  105. package/dist/cjs/lib/view-dns-record-dialog.cjs.map +1 -1
  106. package/dist/cjs/workos-widgets.client.cjs +2 -2
  107. package/dist/cjs/workos-widgets.client.cjs.map +1 -1
  108. package/dist/css/lib/provider-icon.css +93 -3
  109. package/dist/esm/api/endpoint.d.ts +1 -0
  110. package/dist/esm/api/endpoint.js +1 -0
  111. package/dist/esm/api/endpoint.js.map +1 -1
  112. package/dist/esm/index.d.ts +1 -0
  113. package/dist/esm/index.js +3 -1
  114. package/dist/esm/index.js.map +1 -1
  115. package/dist/esm/lib/add-mfa-dialog.js +133 -61
  116. package/dist/esm/lib/add-mfa-dialog.js.map +1 -1
  117. package/dist/esm/lib/admin-portal-domain-verification.js +41 -5
  118. package/dist/esm/lib/admin-portal-domain-verification.js.map +1 -1
  119. package/dist/esm/lib/admin-portal-sso-connection.js +121 -44
  120. package/dist/esm/lib/admin-portal-sso-connection.js.map +1 -1
  121. package/dist/esm/lib/api-keys/api-key-details-card.js +25 -3
  122. package/dist/esm/lib/api-keys/api-key-details-card.js.map +1 -1
  123. package/dist/esm/lib/api-keys/api-key-details-dialog.js +25 -3
  124. package/dist/esm/lib/api-keys/api-key-details-dialog.js.map +1 -1
  125. package/dist/esm/lib/api-keys/api-keys-search.js +13 -4
  126. package/dist/esm/lib/api-keys/api-keys-search.js.map +1 -1
  127. package/dist/esm/lib/api-keys/api-keys-table.js +94 -12
  128. package/dist/esm/lib/api-keys/api-keys-table.js.map +1 -1
  129. package/dist/esm/lib/api-keys/api-keys.js +16 -2
  130. package/dist/esm/lib/api-keys/api-keys.js.map +1 -1
  131. package/dist/esm/lib/api-keys/create-api-key.js +172 -20
  132. package/dist/esm/lib/api-keys/create-api-key.js.map +1 -1
  133. package/dist/esm/lib/api-keys/relative-time.js +12 -2
  134. package/dist/esm/lib/api-keys/relative-time.js.map +1 -1
  135. package/dist/esm/lib/api-keys/revoke-api-key-dialog.js +49 -7
  136. package/dist/esm/lib/api-keys/revoke-api-key-dialog.js.map +1 -1
  137. package/dist/esm/lib/change-password-dialog.js +122 -16
  138. package/dist/esm/lib/change-password-dialog.js.map +1 -1
  139. package/dist/esm/lib/copy-button.d.ts +2 -1
  140. package/dist/esm/lib/copy-button.js +14 -2
  141. package/dist/esm/lib/copy-button.js.map +1 -1
  142. package/dist/esm/lib/delete-domain-dialog.js +52 -19
  143. package/dist/esm/lib/delete-domain-dialog.js.map +1 -1
  144. package/dist/esm/lib/delete-user-dialog.d.ts +2 -2
  145. package/dist/esm/lib/delete-user-dialog.js +36 -11
  146. package/dist/esm/lib/delete-user-dialog.js.map +1 -1
  147. package/dist/esm/lib/domain-actions.js +41 -7
  148. package/dist/esm/lib/domain-actions.js.map +1 -1
  149. package/dist/esm/lib/domain-item.js +42 -8
  150. package/dist/esm/lib/domain-item.js.map +1 -1
  151. package/dist/esm/lib/edit-user-profile-dialog.js +62 -11
  152. package/dist/esm/lib/edit-user-profile-dialog.js.map +1 -1
  153. package/dist/esm/lib/edit-user-role-dialog.js +90 -17
  154. package/dist/esm/lib/edit-user-role-dialog.js.map +1 -1
  155. package/dist/esm/lib/elements.d.ts +5 -2
  156. package/dist/esm/lib/elements.js +14 -3
  157. package/dist/esm/lib/elements.js.map +1 -1
  158. package/dist/esm/lib/elevated-access.js +78 -18
  159. package/dist/esm/lib/elevated-access.js.map +1 -1
  160. package/dist/esm/lib/generic-error.d.ts +5 -1
  161. package/dist/esm/lib/generic-error.js +53 -11
  162. package/dist/esm/lib/generic-error.js.map +1 -1
  163. package/dist/esm/lib/i18n/intl-context.d.ts +29 -0
  164. package/dist/esm/lib/i18n/intl-context.js +12 -0
  165. package/dist/esm/lib/i18n/intl-context.js.map +1 -0
  166. package/dist/esm/lib/i18n/translation.d.ts +16 -0
  167. package/dist/esm/lib/i18n/translation.js +45 -0
  168. package/dist/esm/lib/i18n/translation.js.map +1 -0
  169. package/dist/esm/lib/i18n/use-locale.d.ts +7 -0
  170. package/dist/esm/lib/i18n/use-locale.js +9 -0
  171. package/dist/esm/lib/i18n/use-locale.js.map +1 -0
  172. package/dist/esm/lib/i18n/use-translation.d.ts +15 -0
  173. package/dist/esm/lib/i18n/use-translation.js +23 -0
  174. package/dist/esm/lib/i18n/use-translation.js.map +1 -0
  175. package/dist/esm/lib/identity-providers.d.ts +1 -1
  176. package/dist/esm/lib/invite-user-dialog.js +70 -15
  177. package/dist/esm/lib/invite-user-dialog.js.map +1 -1
  178. package/dist/esm/lib/logout-all-sessions-dialog.js +33 -4
  179. package/dist/esm/lib/logout-all-sessions-dialog.js.map +1 -1
  180. package/dist/esm/lib/logout-dialog.js +34 -10
  181. package/dist/esm/lib/logout-dialog.js.map +1 -1
  182. package/dist/esm/lib/organization-switcher.js +12 -2
  183. package/dist/esm/lib/organization-switcher.js.map +1 -1
  184. package/dist/esm/lib/pipes.js +175 -36
  185. package/dist/esm/lib/pipes.js.map +1 -1
  186. package/dist/esm/lib/resend-invite-dialog.js +67 -17
  187. package/dist/esm/lib/resend-invite-dialog.js.map +1 -1
  188. package/dist/esm/lib/reset-mfa-dialog.js +50 -7
  189. package/dist/esm/lib/reset-mfa-dialog.js.map +1 -1
  190. package/dist/esm/lib/revoke-invite-dialog.js +42 -10
  191. package/dist/esm/lib/revoke-invite-dialog.js.map +1 -1
  192. package/dist/esm/lib/save-button.js +9 -1
  193. package/dist/esm/lib/save-button.js.map +1 -1
  194. package/dist/esm/lib/set-password-dialog.js +101 -13
  195. package/dist/esm/lib/set-password-dialog.js.map +1 -1
  196. package/dist/esm/lib/user-actions-dropdown.js +54 -6
  197. package/dist/esm/lib/user-actions-dropdown.js.map +1 -1
  198. package/dist/esm/lib/user-profile.js +81 -10
  199. package/dist/esm/lib/user-profile.js.map +1 -1
  200. package/dist/esm/lib/user-security.js +127 -25
  201. package/dist/esm/lib/user-security.js.map +1 -1
  202. package/dist/esm/lib/user-sessions.js +74 -15
  203. package/dist/esm/lib/user-sessions.js.map +1 -1
  204. package/dist/esm/lib/users-management.js +266 -51
  205. package/dist/esm/lib/users-management.js.map +1 -1
  206. package/dist/esm/lib/users-search.js +18 -4
  207. package/dist/esm/lib/users-search.js.map +1 -1
  208. package/dist/esm/lib/utils.d.ts +2 -1
  209. package/dist/esm/lib/utils.js +10 -7
  210. package/dist/esm/lib/utils.js.map +1 -1
  211. package/dist/esm/lib/view-dns-record-dialog.js +89 -18
  212. package/dist/esm/lib/view-dns-record-dialog.js.map +1 -1
  213. package/dist/esm/workos-widgets.client.js +2 -2
  214. package/dist/esm/workos-widgets.client.js.map +1 -1
  215. package/package.json +13 -4
@@ -34,6 +34,9 @@ var import_relative_time = require("./relative-time.js");
34
34
  var import_api_keys_context = require("./api-keys-context.js");
35
35
  var import_api_keys_search_provider = require("./api-keys-search-provider.js");
36
36
  var import_api_keys_search = require("./api-keys-search.js");
37
+ var import_translation = require("../i18n/translation.js");
38
+ var import_use_translation = require("../i18n/use-translation.js");
39
+ var import_use_locale = require("../i18n/use-locale.js");
37
40
  function NoApiKeys() {
38
41
  const { clearSearch } = (0, import_api_keys_search_provider.useApiKeysSearchContext)();
39
42
  return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_themes.Flex, { p: "6", gap: "4", justify: "center", align: "center", direction: "column", children: [
@@ -46,9 +49,23 @@ function NoApiKeys() {
46
49
  height: "32px"
47
50
  }
48
51
  ),
49
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_themes.Heading, { size: "5", mb: "1", wrap: "balance", as: "h3", children: "No API keys match your search" })
52
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_themes.Heading, { size: "5", mb: "1", wrap: "balance", as: "h3", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
53
+ import_translation.Translation,
54
+ {
55
+ defaultMessage: "No API keys match your search",
56
+ id: "cKitHb",
57
+ description: "Empty state message when no API keys match search"
58
+ }
59
+ ) })
50
60
  ] }),
51
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_elements.Button, { variant: "secondary", onClick: clearSearch, children: "Clear search" })
61
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_elements.Button, { variant: "secondary", onClick: clearSearch, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
62
+ import_translation.Translation,
63
+ {
64
+ defaultMessage: "Clear search",
65
+ id: "jTupOW",
66
+ description: "Button to clear API key search filters"
67
+ }
68
+ ) })
52
69
  ] });
53
70
  }
54
71
  function ApiKeysTableHeader() {
@@ -59,7 +76,8 @@ function ApiKeysTableHeader() {
59
76
  }
60
77
  function CreatedOn({ createdOn }) {
61
78
  const isHydrated = (0, import_use_is_hydrated.useIsHydrated)();
62
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_jsx_runtime.Fragment, { children: createdOn.toLocaleDateString("en-US", {
79
+ const locale = (0, import_use_locale.useLocale)();
80
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_jsx_runtime.Fragment, { children: createdOn.toLocaleDateString(locale, {
63
81
  timeZone: isHydrated ? void 0 : "UTC",
64
82
  month: "short",
65
83
  day: "numeric",
@@ -69,6 +87,7 @@ function CreatedOn({ createdOn }) {
69
87
  function ApiKeyRow({ apiKey }) {
70
88
  const [revokeDialogOpen, setRevokeDialogOpen] = (0, import_react.useState)(false);
71
89
  const [detailsOpen, setDetailsOpen] = (0, import_react.useState)(false);
90
+ const translate = (0, import_use_translation.useTranslation)();
72
91
  return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
73
92
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
74
93
  import_revoke_api_key_dialog.RevokeApiKeyDialog,
@@ -105,15 +124,36 @@ function ApiKeyRow({ apiKey }) {
105
124
  ) }),
106
125
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_themes.Table.Cell, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_themes.Text, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(CreatedOn, { createdOn: new Date(apiKey.createdAt) }) }) }),
107
126
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_themes.Table.Cell, { justify: "end", children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_elements.DropdownMenu.Root, { children: [
108
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_elements.DropdownMenu.Trigger, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_elements.IconButton, { "aria-label": "API key actions", title: "API key actions", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_icons.DotsHorizontalIcon, {}) }) }),
127
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_elements.DropdownMenu.Trigger, { children: (() => {
128
+ const title = translate({
129
+ defaultMessage: "API key actions",
130
+ id: "RIBfYe",
131
+ description: "Tooltip for API key actions menu button"
132
+ });
133
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_elements.IconButton, { title, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_icons.DotsHorizontalIcon, {}) });
134
+ })() }),
109
135
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_elements.DropdownMenu.Content, { size: "2", align: "end", children: [
110
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_elements.DropdownMenu.Item, { onSelect: () => setDetailsOpen(true), children: "View details" }),
136
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_elements.DropdownMenu.Item, { onSelect: () => setDetailsOpen(true), children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
137
+ import_translation.Translation,
138
+ {
139
+ defaultMessage: "View details",
140
+ id: "VGKbbj",
141
+ description: "Menu item to view API key details"
142
+ }
143
+ ) }),
111
144
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
112
145
  import_elements.DropdownMenu.Item,
113
146
  {
114
147
  variant: "destructive",
115
148
  onSelect: () => setRevokeDialogOpen(true),
116
- children: "Revoke key"
149
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
150
+ import_translation.Translation,
151
+ {
152
+ defaultMessage: "Revoke key",
153
+ id: "KZIJPP",
154
+ description: "Menu item to revoke an API key"
155
+ }
156
+ )
117
157
  }
118
158
  )
119
159
  ] })
@@ -133,10 +173,38 @@ function ApiKeysTable({
133
173
  apiKeys.data.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(NoApiKeys, {}) : /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
134
174
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_themes.Table.Root, { variant: "ghost", size: "2", children: [
135
175
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_themes.Table.Header, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_themes.Table.Row, { children: [
136
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_themes.Table.ColumnHeaderCell, { width: "25%", children: "Name" }),
137
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_themes.Table.ColumnHeaderCell, { width: "25%", children: "Secret key" }),
138
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_themes.Table.ColumnHeaderCell, { width: "25%", children: "Last used" }),
139
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_themes.Table.ColumnHeaderCell, { width: "25%", children: "Created" }),
176
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_themes.Table.ColumnHeaderCell, { width: "25%", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
177
+ import_translation.Translation,
178
+ {
179
+ defaultMessage: "Name",
180
+ id: "VYbVXN",
181
+ description: "Table column header for API key name"
182
+ }
183
+ ) }),
184
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_themes.Table.ColumnHeaderCell, { width: "25%", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
185
+ import_translation.Translation,
186
+ {
187
+ defaultMessage: "Secret key",
188
+ id: "H5k7GB",
189
+ description: "Table column header for API key secret value"
190
+ }
191
+ ) }),
192
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_themes.Table.ColumnHeaderCell, { width: "25%", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
193
+ import_translation.Translation,
194
+ {
195
+ defaultMessage: "Last used",
196
+ id: "E46t3O",
197
+ description: "Table column header for API key last used timestamp"
198
+ }
199
+ ) }),
200
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_themes.Table.ColumnHeaderCell, { width: "25%", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
201
+ import_translation.Translation,
202
+ {
203
+ defaultMessage: "Created",
204
+ id: "CXHhXd",
205
+ description: "Table column header for API key creation date"
206
+ }
207
+ ) }),
140
208
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_themes.Table.ColumnHeaderCell, { width: "28px" })
141
209
  ] }) }),
142
210
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_themes.Table.Body, { children: apiKeys.data.map((apiKey) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ApiKeyRow, { apiKey }, apiKey.id)) })
@@ -152,7 +220,14 @@ function ApiKeysTable({
152
220
  type: "SET_PAGINATION",
153
221
  pagination: { after: apiKeys.listMetadata.after }
154
222
  }),
155
- children: "Previous"
223
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
224
+ import_translation.Translation,
225
+ {
226
+ defaultMessage: "Previous",
227
+ id: "f7TUj0",
228
+ description: "Button to navigate to previous page of API keys"
229
+ }
230
+ )
156
231
  }
157
232
  ),
158
233
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
@@ -165,7 +240,14 @@ function ApiKeysTable({
165
240
  type: "SET_PAGINATION",
166
241
  pagination: { before: apiKeys.listMetadata.before }
167
242
  }),
168
- children: "Next"
243
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
244
+ import_translation.Translation,
245
+ {
246
+ defaultMessage: "Next",
247
+ id: "L2EBxV",
248
+ description: "Button to navigate to next page of API keys"
249
+ }
250
+ )
169
251
  }
170
252
  )
171
253
  ] })
@@ -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\";\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 No API keys match your search\n </Heading>\n </Flex>\n\n <Button variant=\"secondary\" onClick={clearSearch}>\n Clear search\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 return (\n <>\n {createdOn.toLocaleDateString(\"en-US\", {\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 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 <IconButton aria-label=\"API key actions\" title=\"API key actions\">\n <DotsHorizontalIcon />\n </IconButton>\n </DropdownMenu.Trigger>\n <DropdownMenu.Content size=\"2\" align=\"end\">\n <DropdownMenu.Item onSelect={() => setDetailsOpen(true)}>\n View details\n </DropdownMenu.Item>\n <DropdownMenu.Item\n variant=\"destructive\"\n onSelect={() => setRevokeDialogOpen(true)}\n >\n Revoke key\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 Name\n </Table.ColumnHeaderCell>\n <Table.ColumnHeaderCell width=\"25%\">\n Secret key\n </Table.ColumnHeaderCell>\n <Table.ColumnHeaderCell width=\"25%\">\n Last used\n </Table.ColumnHeaderCell>\n <Table.ColumnHeaderCell width=\"25%\">\n Created\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 Previous\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 Next\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\";\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":[]}
@@ -34,6 +34,8 @@ var import_create_api_key = require("./create-api-key.js");
34
34
  var import_utils = require("../utils.js");
35
35
  var import_api_keys_search_provider = require("./api-keys-search-provider.js");
36
36
  var import_api_keys_table = require("./api-keys-table.js");
37
+ var import_translation = require("../i18n/translation.js");
38
+ var import_use_translation = require("../i18n/use-translation.js");
37
39
  const ApiKeys = ({
38
40
  apiKeys,
39
41
  searchQuery,
@@ -48,6 +50,7 @@ const ApiKeys = ({
48
50
  ) });
49
51
  };
50
52
  const ApiKeysLoading = (props) => {
53
+ const translate = (0, import_use_translation.useTranslation)();
51
54
  return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
52
55
  import_themes.Flex,
53
56
  {
@@ -62,11 +65,22 @@ const ApiKeysLoading = (props) => {
62
65
  {
63
66
  name: "api-keys-widget-search",
64
67
  style: { width: "390px" },
65
- placeholder: "Search by name",
68
+ placeholder: translate({
69
+ defaultMessage: "Search by name",
70
+ id: "VBESVz",
71
+ description: "Placeholder for API key search input in loading state"
72
+ }),
66
73
  children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_elements.TextFieldSlot, { side: "left", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_icons.MagnifyingGlassIcon, { "aria-hidden": "true", height: "16", width: "16" }) })
67
74
  }
68
75
  ) }),
69
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_elements.Skeleton, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_elements.Button, { children: "Create API key" }) })
76
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_elements.Skeleton, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_elements.Button, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
77
+ import_translation.Translation,
78
+ {
79
+ defaultMessage: "Create API key",
80
+ id: "eTEzjH",
81
+ description: "Button to create a new API key in loading state"
82
+ }
83
+ ) }) })
70
84
  ] }),
71
85
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
72
86
  import_skeleton_table.SkeletonTable,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/lib/api-keys/api-keys.tsx"],"sourcesContent":["import { Flex } from \"@radix-ui/themes\";\nimport { Button, Skeleton, TextField, TextFieldSlot } from \"../elements.js\";\nimport { GenericError } from \"../generic-error.js\";\nimport { EmptyState } from \"../empty-state.js\";\nimport { MagnifyingGlassIcon } from \"@radix-ui/react-icons\";\nimport { SkeletonTable } from \"./skeleton-table.js\";\nimport { CreateApiKeyButton } from \"./create-api-key.js\";\nimport { getDomProps, WidgetRootDomProps, WidgetRootState } from \"../utils.js\";\nimport { ListOrganizationApiKeysResponse } from \"../../api/endpoint.js\";\nimport { ApiKeysSearchProvider } from \"./api-keys-search-provider.js\";\nimport { ApiKeysTable } from \"./api-keys-table.js\";\n\ninterface ApiKeysProps extends WidgetRootDomProps {\n apiKeys: ListOrganizationApiKeysResponse;\n searchQuery: string | null;\n}\n\nconst ApiKeys: React.FC<ApiKeysProps> = ({\n apiKeys,\n searchQuery,\n ...domProps\n}) => {\n return apiKeys.data.length === 0 && !searchQuery ? (\n <ApiKeysEmptyState {...getWidgetRootDomProps(\"resolved\", domProps)} />\n ) : (\n <ApiKeysSearchProvider>\n <ApiKeysTable\n apiKeys={apiKeys}\n {...getWidgetRootDomProps(\"resolved\", domProps)}\n />\n </ApiKeysSearchProvider>\n );\n};\n\ninterface ApiKeysLoadingProps extends WidgetRootDomProps {}\n\nconst ApiKeysLoading: React.FC<ApiKeysLoadingProps> = (props) => {\n return (\n <Flex\n direction=\"column\"\n align=\"stretch\"\n gap=\"3\"\n {...getWidgetRootDomProps(\"loading\", props)}\n >\n <Flex justify=\"between\" align=\"center\">\n <Skeleton>\n <TextField\n name=\"api-keys-widget-search\"\n style={{ width: \"390px\" }}\n placeholder=\"Search by name\"\n >\n <TextFieldSlot side=\"left\">\n <MagnifyingGlassIcon aria-hidden=\"true\" height=\"16\" width=\"16\" />\n </TextFieldSlot>\n </TextField>\n </Skeleton>\n <Skeleton>\n <Button>Create API key</Button>\n </Skeleton>\n </Flex>\n <SkeletonTable\n numRows={5}\n columns={[\n { children: \"Name\", width: \"25%\" },\n { children: \"Secret key\", width: \"25%\" },\n { children: \"Last used\", width: \"25%\" },\n { children: \"Created\", width: \"25%\" },\n ]}\n />\n </Flex>\n );\n};\n\ninterface ApiKeysErrorProps extends WidgetRootDomProps {\n error: unknown;\n}\n\nconst ApiKeysError: React.FC<ApiKeysErrorProps> = ({ error, ...domProps }) => {\n return (\n <GenericError error={error} {...getWidgetRootDomProps(\"error\", domProps)} />\n );\n};\n\nfunction ApiKeysEmptyState(props: WidgetRootDomProps) {\n return (\n <EmptyState\n heading=\"No API keys yet\"\n message=\"Generate an API key to authenticate and interact with our API.\"\n action={<CreateApiKeyButton />}\n {...props}\n />\n );\n}\n\nfunction getWidgetRootDomProps(\n state: WidgetRootState,\n domProps: WidgetRootDomProps,\n) {\n return getDomProps({\n ...domProps,\n isWidgetRoot: true,\n widgetId: \"api-keys\",\n widgetState: state,\n });\n}\n\nexport type { ApiKeysProps, ApiKeysLoadingProps, ApiKeysErrorProps };\nexport { ApiKeys, ApiKeysLoading, ApiKeysError };\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAuBI;AAvBJ,oBAAqB;AACrB,sBAA2D;AAC3D,2BAA6B;AAC7B,yBAA2B;AAC3B,yBAAoC;AACpC,4BAA8B;AAC9B,4BAAmC;AACnC,mBAAiE;AAEjE,sCAAsC;AACtC,4BAA6B;AAO7B,MAAM,UAAkC,CAAC;AAAA,EACvC;AAAA,EACA;AAAA,EACA,GAAG;AACL,MAAM;AACJ,SAAO,QAAQ,KAAK,WAAW,KAAK,CAAC,cACnC,4CAAC,qBAAmB,GAAG,sBAAsB,YAAY,QAAQ,GAAG,IAEpE,4CAAC,yDACC;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACC,GAAG,sBAAsB,YAAY,QAAQ;AAAA;AAAA,EAChD,GACF;AAEJ;AAIA,MAAM,iBAAgD,CAAC,UAAU;AAC/D,SACE;AAAA,IAAC;AAAA;AAAA,MACC,WAAU;AAAA,MACV,OAAM;AAAA,MACN,KAAI;AAAA,MACH,GAAG,sBAAsB,WAAW,KAAK;AAAA,MAE1C;AAAA,qDAAC,sBAAK,SAAQ,WAAU,OAAM,UAC5B;AAAA,sDAAC,4BACC;AAAA,YAAC;AAAA;AAAA,cACC,MAAK;AAAA,cACL,OAAO,EAAE,OAAO,QAAQ;AAAA,cACxB,aAAY;AAAA,cAEZ,sDAAC,iCAAc,MAAK,QAClB,sDAAC,0CAAoB,eAAY,QAAO,QAAO,MAAK,OAAM,MAAK,GACjE;AAAA;AAAA,UACF,GACF;AAAA,UACA,4CAAC,4BACC,sDAAC,0BAAO,4BAAc,GACxB;AAAA,WACF;AAAA,QACA;AAAA,UAAC;AAAA;AAAA,YACC,SAAS;AAAA,YACT,SAAS;AAAA,cACP,EAAE,UAAU,QAAQ,OAAO,MAAM;AAAA,cACjC,EAAE,UAAU,cAAc,OAAO,MAAM;AAAA,cACvC,EAAE,UAAU,aAAa,OAAO,MAAM;AAAA,cACtC,EAAE,UAAU,WAAW,OAAO,MAAM;AAAA,YACtC;AAAA;AAAA,QACF;AAAA;AAAA;AAAA,EACF;AAEJ;AAMA,MAAM,eAA4C,CAAC,EAAE,OAAO,GAAG,SAAS,MAAM;AAC5E,SACE,4CAAC,qCAAa,OAAe,GAAG,sBAAsB,SAAS,QAAQ,GAAG;AAE9E;AAEA,SAAS,kBAAkB,OAA2B;AACpD,SACE;AAAA,IAAC;AAAA;AAAA,MACC,SAAQ;AAAA,MACR,SAAQ;AAAA,MACR,QAAQ,4CAAC,4CAAmB;AAAA,MAC3B,GAAG;AAAA;AAAA,EACN;AAEJ;AAEA,SAAS,sBACP,OACA,UACA;AACA,aAAO,0BAAY;AAAA,IACjB,GAAG;AAAA,IACH,cAAc;AAAA,IACd,UAAU;AAAA,IACV,aAAa;AAAA,EACf,CAAC;AACH;","names":[]}
1
+ {"version":3,"sources":["../../../../src/lib/api-keys/api-keys.tsx"],"sourcesContent":["import { Flex } from \"@radix-ui/themes\";\nimport { Button, Skeleton, TextField, TextFieldSlot } from \"../elements.js\";\nimport { GenericError } from \"../generic-error.js\";\nimport { EmptyState } from \"../empty-state.js\";\nimport { MagnifyingGlassIcon } from \"@radix-ui/react-icons\";\nimport { SkeletonTable } from \"./skeleton-table.js\";\nimport { CreateApiKeyButton } from \"./create-api-key.js\";\nimport { getDomProps, WidgetRootDomProps, WidgetRootState } from \"../utils.js\";\nimport { ListOrganizationApiKeysResponse } from \"../../api/endpoint.js\";\nimport { ApiKeysSearchProvider } from \"./api-keys-search-provider.js\";\nimport { ApiKeysTable } from \"./api-keys-table.js\";\nimport { Translation } from \"../i18n/translation.js\";\nimport { useTranslation } from \"../i18n/use-translation.js\";\n\ninterface ApiKeysProps extends WidgetRootDomProps {\n apiKeys: ListOrganizationApiKeysResponse;\n searchQuery: string | null;\n}\n\nconst ApiKeys: React.FC<ApiKeysProps> = ({\n apiKeys,\n searchQuery,\n ...domProps\n}) => {\n return apiKeys.data.length === 0 && !searchQuery ? (\n <ApiKeysEmptyState {...getWidgetRootDomProps(\"resolved\", domProps)} />\n ) : (\n <ApiKeysSearchProvider>\n <ApiKeysTable\n apiKeys={apiKeys}\n {...getWidgetRootDomProps(\"resolved\", domProps)}\n />\n </ApiKeysSearchProvider>\n );\n};\n\ninterface ApiKeysLoadingProps extends WidgetRootDomProps {}\n\nconst ApiKeysLoading: React.FC<ApiKeysLoadingProps> = (props) => {\n const translate = useTranslation();\n return (\n <Flex\n direction=\"column\"\n align=\"stretch\"\n gap=\"3\"\n {...getWidgetRootDomProps(\"loading\", props)}\n >\n <Flex justify=\"between\" align=\"center\">\n <Skeleton>\n <TextField\n name=\"api-keys-widget-search\"\n style={{ width: \"390px\" }}\n placeholder={translate({\n defaultMessage: \"Search by name\",\n id: \"VBESVz\",\n description:\n \"Placeholder for API key search input in loading state\",\n })}\n >\n <TextFieldSlot side=\"left\">\n <MagnifyingGlassIcon aria-hidden=\"true\" height=\"16\" width=\"16\" />\n </TextFieldSlot>\n </TextField>\n </Skeleton>\n <Skeleton>\n <Button>\n <Translation\n defaultMessage=\"Create API key\"\n id=\"eTEzjH\"\n description=\"Button to create a new API key in loading state\"\n />\n </Button>\n </Skeleton>\n </Flex>\n <SkeletonTable\n numRows={5}\n columns={[\n { children: \"Name\", width: \"25%\" },\n { children: \"Secret key\", width: \"25%\" },\n { children: \"Last used\", width: \"25%\" },\n { children: \"Created\", width: \"25%\" },\n ]}\n />\n </Flex>\n );\n};\n\ninterface ApiKeysErrorProps extends WidgetRootDomProps {\n error: unknown;\n}\n\nconst ApiKeysError: React.FC<ApiKeysErrorProps> = ({ error, ...domProps }) => {\n return (\n <GenericError error={error} {...getWidgetRootDomProps(\"error\", domProps)} />\n );\n};\n\nfunction ApiKeysEmptyState(props: WidgetRootDomProps) {\n return (\n <EmptyState\n heading=\"No API keys yet\"\n message=\"Generate an API key to authenticate and interact with our API.\"\n action={<CreateApiKeyButton />}\n {...props}\n />\n );\n}\n\nfunction getWidgetRootDomProps(\n state: WidgetRootState,\n domProps: WidgetRootDomProps,\n) {\n return getDomProps({\n ...domProps,\n isWidgetRoot: true,\n widgetId: \"api-keys\",\n widgetState: state,\n });\n}\n\nexport type { ApiKeysProps, ApiKeysLoadingProps, ApiKeysErrorProps };\nexport { ApiKeys, ApiKeysLoading, ApiKeysError };\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAyBI;AAzBJ,oBAAqB;AACrB,sBAA2D;AAC3D,2BAA6B;AAC7B,yBAA2B;AAC3B,yBAAoC;AACpC,4BAA8B;AAC9B,4BAAmC;AACnC,mBAAiE;AAEjE,sCAAsC;AACtC,4BAA6B;AAC7B,yBAA4B;AAC5B,6BAA+B;AAO/B,MAAM,UAAkC,CAAC;AAAA,EACvC;AAAA,EACA;AAAA,EACA,GAAG;AACL,MAAM;AACJ,SAAO,QAAQ,KAAK,WAAW,KAAK,CAAC,cACnC,4CAAC,qBAAmB,GAAG,sBAAsB,YAAY,QAAQ,GAAG,IAEpE,4CAAC,yDACC;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACC,GAAG,sBAAsB,YAAY,QAAQ;AAAA;AAAA,EAChD,GACF;AAEJ;AAIA,MAAM,iBAAgD,CAAC,UAAU;AAC/D,QAAM,gBAAY,uCAAe;AACjC,SACE;AAAA,IAAC;AAAA;AAAA,MACC,WAAU;AAAA,MACV,OAAM;AAAA,MACN,KAAI;AAAA,MACH,GAAG,sBAAsB,WAAW,KAAK;AAAA,MAE1C;AAAA,qDAAC,sBAAK,SAAQ,WAAU,OAAM,UAC5B;AAAA,sDAAC,4BACC;AAAA,YAAC;AAAA;AAAA,cACC,MAAK;AAAA,cACL,OAAO,EAAE,OAAO,QAAQ;AAAA,cACxB,aAAa,UAAU;AAAA,gBACrB,gBAAgB;AAAA,gBAChB,IAAI;AAAA,gBACJ,aACE;AAAA,cACJ,CAAC;AAAA,cAED,sDAAC,iCAAc,MAAK,QAClB,sDAAC,0CAAoB,eAAY,QAAO,QAAO,MAAK,OAAM,MAAK,GACjE;AAAA;AAAA,UACF,GACF;AAAA,UACA,4CAAC,4BACC,sDAAC,0BACC;AAAA,YAAC;AAAA;AAAA,cACC,gBAAe;AAAA,cACf,IAAG;AAAA,cACH,aAAY;AAAA;AAAA,UACd,GACF,GACF;AAAA,WACF;AAAA,QACA;AAAA,UAAC;AAAA;AAAA,YACC,SAAS;AAAA,YACT,SAAS;AAAA,cACP,EAAE,UAAU,QAAQ,OAAO,MAAM;AAAA,cACjC,EAAE,UAAU,cAAc,OAAO,MAAM;AAAA,cACvC,EAAE,UAAU,aAAa,OAAO,MAAM;AAAA,cACtC,EAAE,UAAU,WAAW,OAAO,MAAM;AAAA,YACtC;AAAA;AAAA,QACF;AAAA;AAAA;AAAA,EACF;AAEJ;AAMA,MAAM,eAA4C,CAAC,EAAE,OAAO,GAAG,SAAS,MAAM;AAC5E,SACE,4CAAC,qCAAa,OAAe,GAAG,sBAAsB,SAAS,QAAQ,GAAG;AAE9E;AAEA,SAAS,kBAAkB,OAA2B;AACpD,SACE;AAAA,IAAC;AAAA;AAAA,MACC,SAAQ;AAAA,MACR,SAAQ;AAAA,MACR,QAAQ,4CAAC,4CAAmB;AAAA,MAC3B,GAAG;AAAA;AAAA,EACN;AAEJ;AAEA,SAAS,sBACP,OACA,UACA;AACA,aAAO,0BAAY;AAAA,IACjB,GAAG;AAAA,IACH,cAAc;AAAA,IACd,UAAU;AAAA,IACV,aAAa;AAAA,EACf,CAAC;AACH;","names":[]}
@@ -39,10 +39,11 @@ var Form = __toESM(require("@radix-ui/react-form"), 1);
39
39
  var import_react_icons = require("@radix-ui/react-icons");
40
40
  var import_copy_button = require("../copy-button.js");
41
41
  var React = __toESM(require("react"), 1);
42
- var import_utils = require("../utils.js");
43
42
  var import_endpoint = require("../../api/endpoint.js");
44
43
  var import_api_key = require("../api/api-key.js");
45
44
  var import_api_keys_context = require("./api-keys-context.js");
45
+ var import_translation = require("../i18n/translation.js");
46
+ var import_use_translation = require("../i18n/use-translation.js");
46
47
  function CreateApiKeyDialog() {
47
48
  const {
48
49
  state: { createDialogOpen, createdApiKey },
@@ -67,6 +68,7 @@ function CreateApiKeyDialog() {
67
68
  }
68
69
  function CreateApiKeyForm() {
69
70
  const { dispatch } = (0, import_api_keys_context.useApiKeysContext)();
71
+ const translate = (0, import_use_translation.useTranslation)();
70
72
  const [errors, setErrors] = React.useState({ name: false });
71
73
  const validate = (formData) => {
72
74
  const name = formData.get("name")?.toString() ?? "";
@@ -83,7 +85,14 @@ function CreateApiKeyForm() {
83
85
  } = (0, import_api_key.useCreateApiKey)();
84
86
  const permissions = (0, import_endpoint.useListOrganizationApiKeyPermissions)({ limit: 100 });
85
87
  return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_elements.Dialog.Content, { maxWidth: "529px", children: [
86
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_elements.Dialog.Title, { size: "4", weight: "bold", children: "Create API key" }),
88
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_elements.Dialog.Title, { size: "4", weight: "bold", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
89
+ import_translation.Translation,
90
+ {
91
+ defaultMessage: "Create API key",
92
+ id: "eUFRNS",
93
+ description: "Dialog title for creating a new API key"
94
+ }
95
+ ) }),
87
96
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
88
97
  Form.Root,
89
98
  {
@@ -113,25 +122,64 @@ function CreateApiKeyForm() {
113
122
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_themes.Flex, { direction: "column", align: "stretch", gap: "4", children: [
114
123
  error && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_themes.Callout.Root, { color: "red", role: "alert", children: [
115
124
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_themes.Callout.Icon, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_icons.ExclamationTriangleIcon, {}) }),
116
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_themes.Callout.Text, { children: "An error occurred while creating the API key." })
125
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_themes.Callout.Text, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
126
+ import_translation.Translation,
127
+ {
128
+ defaultMessage: "An error occurred while creating the API key.",
129
+ id: "0LyBVd",
130
+ description: "Error message when API key creation fails"
131
+ }
132
+ ) })
117
133
  ] }),
118
134
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Form.Field, { name: "name", asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_themes.Flex, { direction: "column", align: "stretch", gap: "2", children: [
119
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Form.Label, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_elements.Label, { children: "Name" }) }),
135
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Form.Label, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_elements.Label, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
136
+ import_translation.Translation,
137
+ {
138
+ defaultMessage: "Name",
139
+ id: "v0VmRy",
140
+ description: "Label for API key name input field"
141
+ }
142
+ ) }) }),
120
143
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Form.Control, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
121
144
  import_elements.TextField,
122
145
  {
123
146
  "data-1p-ignore": true,
124
147
  autoComplete: "off",
125
- placeholder: "A descriptive name for the API key"
148
+ placeholder: translate({
149
+ defaultMessage: "A descriptive name for the API key",
150
+ id: "moyvr4",
151
+ description: "Placeholder for API key name input"
152
+ })
126
153
  }
127
154
  ) }),
128
- errors.name && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Form.Message, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_themes.Text, { size: "2", color: "red", children: "The name is required" }) })
155
+ errors.name && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Form.Message, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_themes.Text, { size: "2", color: "red", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
156
+ import_translation.Translation,
157
+ {
158
+ defaultMessage: "The name is required",
159
+ id: "oF9d2V",
160
+ description: "Validation error when API key name is empty"
161
+ }
162
+ ) }) })
129
163
  ] }) }),
130
164
  permissions.isSuccess && permissions.data.data.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(PermissionsField, { permissions: permissions.data.data })
131
165
  ] }),
132
166
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_themes.Flex, { align: "center", gap: "3", justify: "end", mt: "5", children: [
133
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_elements.Dialog.Close, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_elements.Button, { variant: "secondary", disabled: isPending || isSuccess, children: "Cancel" }) }),
134
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_elements.Button, { type: "submit", loading: isPending || isSuccess, children: "Create API key" })
167
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_elements.Dialog.Close, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_elements.Button, { variant: "secondary", disabled: isPending || isSuccess, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
168
+ import_translation.Translation,
169
+ {
170
+ defaultMessage: "Cancel",
171
+ id: "AyVAAW",
172
+ description: "Button to cancel API key creation"
173
+ }
174
+ ) }) }),
175
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_elements.Button, { type: "submit", loading: isPending || isSuccess, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
176
+ import_translation.Translation,
177
+ {
178
+ defaultMessage: "Create API key",
179
+ id: "d4BNWL",
180
+ description: "Button to submit and create the API key"
181
+ }
182
+ ) })
135
183
  ] })
136
184
  ]
137
185
  }
@@ -140,14 +188,42 @@ function CreateApiKeyForm() {
140
188
  }
141
189
  function SaveApiKeyContent({ apiKey }) {
142
190
  return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_elements.Dialog.Content, { maxWidth: "529px", children: [
143
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_elements.Dialog.Title, { size: "4", weight: "bold", children: "Save your key" }),
144
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_elements.Dialog.Description, { size: "2", children: "Please save this API key in a secure location. If you lose it, you'll need to generate a new one." }),
191
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_elements.Dialog.Title, { size: "4", weight: "bold", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
192
+ import_translation.Translation,
193
+ {
194
+ defaultMessage: "Save your key",
195
+ id: "wFFCij",
196
+ description: "Dialog title prompting user to save their API key"
197
+ }
198
+ ) }),
199
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_elements.Dialog.Description, { size: "2", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
200
+ import_translation.Translation,
201
+ {
202
+ defaultMessage: "Please save this API key in a secure location. If you lose it, you'll need to generate a new one.",
203
+ id: "sy+2x7",
204
+ description: "Warning message about saving the API key"
205
+ }
206
+ ) }),
145
207
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_themes.Callout.Root, { mt: "5", mb: "4", children: [
146
208
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_themes.Callout.Icon, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_icons.InfoCircledIcon, {}) }),
147
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_themes.Callout.Text, { children: "You won't be able to access the key again. Please copy it now." })
209
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_themes.Callout.Text, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
210
+ import_translation.Translation,
211
+ {
212
+ defaultMessage: "You won't be able to access the key again. Please copy it now.",
213
+ id: "EFAK/K",
214
+ description: "Callout warning that the key won't be accessible again"
215
+ }
216
+ ) })
148
217
  ] }),
149
218
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_elements.TextField, { value: apiKey, readOnly: true, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_elements.TextFieldSlot, { side: "right", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_copy_button.CopyIconButton, { value: apiKey }) }) }),
150
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_themes.Flex, { align: "center", gap: "3", justify: "end", mt: "5", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_elements.Dialog.Close, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_copy_button.CopyButton, { value: apiKey, children: "Copy and close" }) }) })
219
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_themes.Flex, { align: "center", gap: "3", justify: "end", mt: "5", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_elements.Dialog.Close, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_copy_button.CopyButton, { value: apiKey, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
220
+ import_translation.Translation,
221
+ {
222
+ defaultMessage: "Copy and close",
223
+ id: "ViYtvQ",
224
+ description: "Button to copy API key and close dialog"
225
+ }
226
+ ) }) }) })
151
227
  ] });
152
228
  }
153
229
  function Permission({
@@ -192,6 +268,7 @@ function PermissionsField({
192
268
  const [selectedPermissions, setSelectedPermissions] = React.useState([]);
193
269
  const [filter, setFilter] = React.useState("");
194
270
  const fieldRef = React.useRef(null);
271
+ const translate = (0, import_use_translation.useTranslation)();
195
272
  const filteredPermissions = React.useMemo(() => {
196
273
  return permissions.filter((p) => {
197
274
  return !filter.trim().length || p.description?.toLowerCase().match(filter.toLowerCase()) || p.name.toLowerCase().match(filter.toLowerCase()) || p.slug.toLowerCase().match(filter.toLowerCase());
@@ -209,8 +286,22 @@ function PermissionsField({
209
286
  };
210
287
  }, [filteredPermissions.length]);
211
288
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Form.Field, { name: "permissions", asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_themes.Flex, { direction: "column", align: "stretch", gap: "1", children: [
212
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Form.Label, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_elements.Label, { children: "Permissions" }) }),
213
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_themes.Text, { size: "2", mb: "2", color: "gray", children: "Only enable the minimum permissions required for your use case." }),
289
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Form.Label, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_elements.Label, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
290
+ import_translation.Translation,
291
+ {
292
+ defaultMessage: "Permissions",
293
+ id: "6YN1wO",
294
+ description: "Label for API key permissions field"
295
+ }
296
+ ) }) }),
297
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_themes.Text, { size: "2", mb: "2", color: "gray", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
298
+ import_translation.Translation,
299
+ {
300
+ defaultMessage: "Only enable the minimum permissions required for your use case.",
301
+ id: "q2VEtG",
302
+ description: "Help text for API key permissions selection"
303
+ }
304
+ ) }),
214
305
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
215
306
  import_themes.Flex,
216
307
  {
@@ -241,7 +332,11 @@ function PermissionsField({
241
332
  borderRadius: "var(--radius-3) var(--radius-3) 0 0",
242
333
  boxShadow: "none"
243
334
  },
244
- placeholder: "Search",
335
+ placeholder: translate({
336
+ defaultMessage: "Search",
337
+ id: "iyNcly",
338
+ description: "Placeholder for permissions search input"
339
+ }),
245
340
  children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_elements.TextFieldSlot, { side: "left", px: "3", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_icons.MagnifyingGlassIcon, { "aria-hidden": "true", height: "16", width: "16" }) })
246
341
  }
247
342
  ),
@@ -316,14 +411,28 @@ function PermissionsField({
316
411
  }
317
412
  }
318
413
  ),
319
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_themes.Text, { size: "2", align: "center", mb: "2", wrap: "balance", weight: "bold", children: "No permissions match your search" }),
414
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_themes.Text, { size: "2", align: "center", mb: "2", wrap: "balance", weight: "bold", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
415
+ import_translation.Translation,
416
+ {
417
+ defaultMessage: "No permissions match your search",
418
+ id: "xjqT9f",
419
+ description: "Empty state message when no permissions match search"
420
+ }
421
+ ) }),
320
422
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
321
423
  import_elements.Button,
322
424
  {
323
425
  variant: "secondary",
324
426
  size: "1",
325
427
  onClick: () => setFilter(""),
326
- children: "Clear search"
428
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
429
+ import_translation.Translation,
430
+ {
431
+ defaultMessage: "Clear search",
432
+ id: "YrMs63",
433
+ description: "Button to clear permissions search"
434
+ }
435
+ )
327
436
  }
328
437
  )
329
438
  ]
@@ -340,14 +449,50 @@ function SelectedPermissions({
340
449
  onToggle
341
450
  }) {
342
451
  return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_themes.Flex, { align: "center", gap: "2", children: [
343
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_themes.Text, { size: "1", style: { lineHeight: 1, color: "var(--gray-11)" }, children: selected === 0 ? "No permissions selected" : `${(0, import_utils.pluralize)("permission", selected)} selected` }),
452
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_themes.Text, { size: "1", style: { lineHeight: 1, color: "var(--gray-11)" }, children: selected === 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
453
+ import_translation.Translation,
454
+ {
455
+ defaultMessage: "No permissions selected",
456
+ id: "FqU9hv",
457
+ description: "Message when no permissions are selected"
458
+ }
459
+ ) : selected === 1 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
460
+ import_translation.Translation,
461
+ {
462
+ defaultMessage: "1 permission selected",
463
+ id: "VouLgT",
464
+ description: "Message showing count of selected permissions"
465
+ }
466
+ ) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
467
+ import_translation.Translation,
468
+ {
469
+ defaultMessage: "{count} permissions selected",
470
+ id: "ZL90DI",
471
+ description: "Message showing count of selected permissions",
472
+ values: { count: selected }
473
+ }
474
+ ) }),
344
475
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
345
476
  import_themes.Text,
346
477
  {
347
478
  size: "1",
348
479
  onClick: onToggle,
349
480
  style: { cursor: "pointer", color: "var(--accent-10)" },
350
- children: total === selected ? "Deselect all" : "Select all"
481
+ children: total === selected ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
482
+ import_translation.Translation,
483
+ {
484
+ defaultMessage: "Deselect all",
485
+ id: "63f7SY",
486
+ description: "Button to deselect all permissions"
487
+ }
488
+ ) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
489
+ import_translation.Translation,
490
+ {
491
+ defaultMessage: "Select all",
492
+ id: "onTqlA",
493
+ description: "Button to select all permissions"
494
+ }
495
+ )
351
496
  }
352
497
  )
353
498
  ] });
@@ -359,7 +504,14 @@ function CreateApiKeyButton() {
359
504
  {
360
505
  variant: "secondary",
361
506
  onClick: () => dispatch({ type: "OPEN_CREATE_DIALOG" }),
362
- children: "Create API key"
507
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
508
+ import_translation.Translation,
509
+ {
510
+ defaultMessage: "Create API key",
511
+ id: "vq5724",
512
+ description: "Button to open create API key dialog"
513
+ }
514
+ )
363
515
  }
364
516
  );
365
517
  }