@workos-inc/widgets 1.7.2 → 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 (214) hide show
  1. package/CHANGELOG.md +5 -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/esm/api/endpoint.d.ts +1 -0
  109. package/dist/esm/api/endpoint.js +1 -0
  110. package/dist/esm/api/endpoint.js.map +1 -1
  111. package/dist/esm/index.d.ts +1 -0
  112. package/dist/esm/index.js +3 -1
  113. package/dist/esm/index.js.map +1 -1
  114. package/dist/esm/lib/add-mfa-dialog.js +133 -61
  115. package/dist/esm/lib/add-mfa-dialog.js.map +1 -1
  116. package/dist/esm/lib/admin-portal-domain-verification.js +41 -5
  117. package/dist/esm/lib/admin-portal-domain-verification.js.map +1 -1
  118. package/dist/esm/lib/admin-portal-sso-connection.js +121 -44
  119. package/dist/esm/lib/admin-portal-sso-connection.js.map +1 -1
  120. package/dist/esm/lib/api-keys/api-key-details-card.js +25 -3
  121. package/dist/esm/lib/api-keys/api-key-details-card.js.map +1 -1
  122. package/dist/esm/lib/api-keys/api-key-details-dialog.js +25 -3
  123. package/dist/esm/lib/api-keys/api-key-details-dialog.js.map +1 -1
  124. package/dist/esm/lib/api-keys/api-keys-search.js +13 -4
  125. package/dist/esm/lib/api-keys/api-keys-search.js.map +1 -1
  126. package/dist/esm/lib/api-keys/api-keys-table.js +94 -12
  127. package/dist/esm/lib/api-keys/api-keys-table.js.map +1 -1
  128. package/dist/esm/lib/api-keys/api-keys.js +16 -2
  129. package/dist/esm/lib/api-keys/api-keys.js.map +1 -1
  130. package/dist/esm/lib/api-keys/create-api-key.js +172 -20
  131. package/dist/esm/lib/api-keys/create-api-key.js.map +1 -1
  132. package/dist/esm/lib/api-keys/relative-time.js +12 -2
  133. package/dist/esm/lib/api-keys/relative-time.js.map +1 -1
  134. package/dist/esm/lib/api-keys/revoke-api-key-dialog.js +49 -7
  135. package/dist/esm/lib/api-keys/revoke-api-key-dialog.js.map +1 -1
  136. package/dist/esm/lib/change-password-dialog.js +122 -16
  137. package/dist/esm/lib/change-password-dialog.js.map +1 -1
  138. package/dist/esm/lib/copy-button.d.ts +2 -1
  139. package/dist/esm/lib/copy-button.js +14 -2
  140. package/dist/esm/lib/copy-button.js.map +1 -1
  141. package/dist/esm/lib/delete-domain-dialog.js +52 -19
  142. package/dist/esm/lib/delete-domain-dialog.js.map +1 -1
  143. package/dist/esm/lib/delete-user-dialog.d.ts +2 -2
  144. package/dist/esm/lib/delete-user-dialog.js +36 -11
  145. package/dist/esm/lib/delete-user-dialog.js.map +1 -1
  146. package/dist/esm/lib/domain-actions.js +41 -7
  147. package/dist/esm/lib/domain-actions.js.map +1 -1
  148. package/dist/esm/lib/domain-item.js +42 -8
  149. package/dist/esm/lib/domain-item.js.map +1 -1
  150. package/dist/esm/lib/edit-user-profile-dialog.js +62 -11
  151. package/dist/esm/lib/edit-user-profile-dialog.js.map +1 -1
  152. package/dist/esm/lib/edit-user-role-dialog.js +90 -17
  153. package/dist/esm/lib/edit-user-role-dialog.js.map +1 -1
  154. package/dist/esm/lib/elements.d.ts +5 -2
  155. package/dist/esm/lib/elements.js +14 -3
  156. package/dist/esm/lib/elements.js.map +1 -1
  157. package/dist/esm/lib/elevated-access.js +78 -18
  158. package/dist/esm/lib/elevated-access.js.map +1 -1
  159. package/dist/esm/lib/generic-error.d.ts +5 -1
  160. package/dist/esm/lib/generic-error.js +53 -11
  161. package/dist/esm/lib/generic-error.js.map +1 -1
  162. package/dist/esm/lib/i18n/intl-context.d.ts +29 -0
  163. package/dist/esm/lib/i18n/intl-context.js +12 -0
  164. package/dist/esm/lib/i18n/intl-context.js.map +1 -0
  165. package/dist/esm/lib/i18n/translation.d.ts +16 -0
  166. package/dist/esm/lib/i18n/translation.js +45 -0
  167. package/dist/esm/lib/i18n/translation.js.map +1 -0
  168. package/dist/esm/lib/i18n/use-locale.d.ts +7 -0
  169. package/dist/esm/lib/i18n/use-locale.js +9 -0
  170. package/dist/esm/lib/i18n/use-locale.js.map +1 -0
  171. package/dist/esm/lib/i18n/use-translation.d.ts +15 -0
  172. package/dist/esm/lib/i18n/use-translation.js +23 -0
  173. package/dist/esm/lib/i18n/use-translation.js.map +1 -0
  174. package/dist/esm/lib/identity-providers.d.ts +1 -1
  175. package/dist/esm/lib/invite-user-dialog.js +70 -15
  176. package/dist/esm/lib/invite-user-dialog.js.map +1 -1
  177. package/dist/esm/lib/logout-all-sessions-dialog.js +33 -4
  178. package/dist/esm/lib/logout-all-sessions-dialog.js.map +1 -1
  179. package/dist/esm/lib/logout-dialog.js +34 -10
  180. package/dist/esm/lib/logout-dialog.js.map +1 -1
  181. package/dist/esm/lib/organization-switcher.js +12 -2
  182. package/dist/esm/lib/organization-switcher.js.map +1 -1
  183. package/dist/esm/lib/pipes.js +175 -36
  184. package/dist/esm/lib/pipes.js.map +1 -1
  185. package/dist/esm/lib/resend-invite-dialog.js +67 -17
  186. package/dist/esm/lib/resend-invite-dialog.js.map +1 -1
  187. package/dist/esm/lib/reset-mfa-dialog.js +50 -7
  188. package/dist/esm/lib/reset-mfa-dialog.js.map +1 -1
  189. package/dist/esm/lib/revoke-invite-dialog.js +42 -10
  190. package/dist/esm/lib/revoke-invite-dialog.js.map +1 -1
  191. package/dist/esm/lib/save-button.js +9 -1
  192. package/dist/esm/lib/save-button.js.map +1 -1
  193. package/dist/esm/lib/set-password-dialog.js +101 -13
  194. package/dist/esm/lib/set-password-dialog.js.map +1 -1
  195. package/dist/esm/lib/user-actions-dropdown.js +54 -6
  196. package/dist/esm/lib/user-actions-dropdown.js.map +1 -1
  197. package/dist/esm/lib/user-profile.js +81 -10
  198. package/dist/esm/lib/user-profile.js.map +1 -1
  199. package/dist/esm/lib/user-security.js +127 -25
  200. package/dist/esm/lib/user-security.js.map +1 -1
  201. package/dist/esm/lib/user-sessions.js +74 -15
  202. package/dist/esm/lib/user-sessions.js.map +1 -1
  203. package/dist/esm/lib/users-management.js +266 -51
  204. package/dist/esm/lib/users-management.js.map +1 -1
  205. package/dist/esm/lib/users-search.js +18 -4
  206. package/dist/esm/lib/users-search.js.map +1 -1
  207. package/dist/esm/lib/utils.d.ts +2 -1
  208. package/dist/esm/lib/utils.js +10 -7
  209. package/dist/esm/lib/utils.js.map +1 -1
  210. package/dist/esm/lib/view-dns-record-dialog.js +89 -18
  211. package/dist/esm/lib/view-dns-record-dialog.js.map +1 -1
  212. package/dist/esm/workos-widgets.client.js +2 -2
  213. package/dist/esm/workos-widgets.client.js.map +1 -1
  214. package/package.json +11 -2
@@ -11,6 +11,9 @@ import { RelativeTime } from "./relative-time.js";
11
11
  import { useApiKeysContext } from "./api-keys-context.js";
12
12
  import { useApiKeysSearchContext } from "./api-keys-search-provider.js";
13
13
  import { ApiKeysSearch } from "./api-keys-search.js";
14
+ import { Translation } from "../i18n/translation.js";
15
+ import { useTranslation } from "../i18n/use-translation.js";
16
+ import { useLocale } from "../i18n/use-locale.js";
14
17
  function NoApiKeys() {
15
18
  const { clearSearch } = useApiKeysSearchContext();
16
19
  return /* @__PURE__ */ jsxs(Flex, { p: "6", gap: "4", justify: "center", align: "center", direction: "column", children: [
@@ -23,9 +26,23 @@ function NoApiKeys() {
23
26
  height: "32px"
24
27
  }
25
28
  ),
26
- /* @__PURE__ */ jsx(Heading, { size: "5", mb: "1", wrap: "balance", as: "h3", children: "No API keys match your search" })
29
+ /* @__PURE__ */ jsx(Heading, { size: "5", mb: "1", wrap: "balance", as: "h3", children: /* @__PURE__ */ jsx(
30
+ Translation,
31
+ {
32
+ defaultMessage: "No API keys match your search",
33
+ id: "cKitHb",
34
+ description: "Empty state message when no API keys match search"
35
+ }
36
+ ) })
27
37
  ] }),
28
- /* @__PURE__ */ jsx(Button, { variant: "secondary", onClick: clearSearch, children: "Clear search" })
38
+ /* @__PURE__ */ jsx(Button, { variant: "secondary", onClick: clearSearch, children: /* @__PURE__ */ jsx(
39
+ Translation,
40
+ {
41
+ defaultMessage: "Clear search",
42
+ id: "jTupOW",
43
+ description: "Button to clear API key search filters"
44
+ }
45
+ ) })
29
46
  ] });
30
47
  }
31
48
  function ApiKeysTableHeader() {
@@ -36,7 +53,8 @@ function ApiKeysTableHeader() {
36
53
  }
37
54
  function CreatedOn({ createdOn }) {
38
55
  const isHydrated = useIsHydrated();
39
- return /* @__PURE__ */ jsx(Fragment, { children: createdOn.toLocaleDateString("en-US", {
56
+ const locale = useLocale();
57
+ return /* @__PURE__ */ jsx(Fragment, { children: createdOn.toLocaleDateString(locale, {
40
58
  timeZone: isHydrated ? void 0 : "UTC",
41
59
  month: "short",
42
60
  day: "numeric",
@@ -46,6 +64,7 @@ function CreatedOn({ createdOn }) {
46
64
  function ApiKeyRow({ apiKey }) {
47
65
  const [revokeDialogOpen, setRevokeDialogOpen] = useState(false);
48
66
  const [detailsOpen, setDetailsOpen] = useState(false);
67
+ const translate = useTranslation();
49
68
  return /* @__PURE__ */ jsxs(Fragment, { children: [
50
69
  /* @__PURE__ */ jsx(
51
70
  RevokeApiKeyDialog,
@@ -82,15 +101,36 @@ function ApiKeyRow({ apiKey }) {
82
101
  ) }),
83
102
  /* @__PURE__ */ jsx(Table.Cell, { children: /* @__PURE__ */ jsx(Text, { children: /* @__PURE__ */ jsx(CreatedOn, { createdOn: new Date(apiKey.createdAt) }) }) }),
84
103
  /* @__PURE__ */ jsx(Table.Cell, { justify: "end", children: /* @__PURE__ */ jsxs(DropdownMenu.Root, { children: [
85
- /* @__PURE__ */ jsx(DropdownMenu.Trigger, { children: /* @__PURE__ */ jsx(IconButton, { "aria-label": "API key actions", title: "API key actions", children: /* @__PURE__ */ jsx(DotsHorizontalIcon, {}) }) }),
104
+ /* @__PURE__ */ jsx(DropdownMenu.Trigger, { children: (() => {
105
+ const title = translate({
106
+ defaultMessage: "API key actions",
107
+ id: "RIBfYe",
108
+ description: "Tooltip for API key actions menu button"
109
+ });
110
+ return /* @__PURE__ */ jsx(IconButton, { title, children: /* @__PURE__ */ jsx(DotsHorizontalIcon, {}) });
111
+ })() }),
86
112
  /* @__PURE__ */ jsxs(DropdownMenu.Content, { size: "2", align: "end", children: [
87
- /* @__PURE__ */ jsx(DropdownMenu.Item, { onSelect: () => setDetailsOpen(true), children: "View details" }),
113
+ /* @__PURE__ */ jsx(DropdownMenu.Item, { onSelect: () => setDetailsOpen(true), children: /* @__PURE__ */ jsx(
114
+ Translation,
115
+ {
116
+ defaultMessage: "View details",
117
+ id: "VGKbbj",
118
+ description: "Menu item to view API key details"
119
+ }
120
+ ) }),
88
121
  /* @__PURE__ */ jsx(
89
122
  DropdownMenu.Item,
90
123
  {
91
124
  variant: "destructive",
92
125
  onSelect: () => setRevokeDialogOpen(true),
93
- children: "Revoke key"
126
+ children: /* @__PURE__ */ jsx(
127
+ Translation,
128
+ {
129
+ defaultMessage: "Revoke key",
130
+ id: "KZIJPP",
131
+ description: "Menu item to revoke an API key"
132
+ }
133
+ )
94
134
  }
95
135
  )
96
136
  ] })
@@ -110,10 +150,38 @@ function ApiKeysTable({
110
150
  apiKeys.data.length === 0 ? /* @__PURE__ */ jsx(NoApiKeys, {}) : /* @__PURE__ */ jsxs(Fragment, { children: [
111
151
  /* @__PURE__ */ jsxs(Table.Root, { variant: "ghost", size: "2", children: [
112
152
  /* @__PURE__ */ jsx(Table.Header, { children: /* @__PURE__ */ jsxs(Table.Row, { children: [
113
- /* @__PURE__ */ jsx(Table.ColumnHeaderCell, { width: "25%", children: "Name" }),
114
- /* @__PURE__ */ jsx(Table.ColumnHeaderCell, { width: "25%", children: "Secret key" }),
115
- /* @__PURE__ */ jsx(Table.ColumnHeaderCell, { width: "25%", children: "Last used" }),
116
- /* @__PURE__ */ jsx(Table.ColumnHeaderCell, { width: "25%", children: "Created" }),
153
+ /* @__PURE__ */ jsx(Table.ColumnHeaderCell, { width: "25%", children: /* @__PURE__ */ jsx(
154
+ Translation,
155
+ {
156
+ defaultMessage: "Name",
157
+ id: "VYbVXN",
158
+ description: "Table column header for API key name"
159
+ }
160
+ ) }),
161
+ /* @__PURE__ */ jsx(Table.ColumnHeaderCell, { width: "25%", children: /* @__PURE__ */ jsx(
162
+ Translation,
163
+ {
164
+ defaultMessage: "Secret key",
165
+ id: "H5k7GB",
166
+ description: "Table column header for API key secret value"
167
+ }
168
+ ) }),
169
+ /* @__PURE__ */ jsx(Table.ColumnHeaderCell, { width: "25%", children: /* @__PURE__ */ jsx(
170
+ Translation,
171
+ {
172
+ defaultMessage: "Last used",
173
+ id: "E46t3O",
174
+ description: "Table column header for API key last used timestamp"
175
+ }
176
+ ) }),
177
+ /* @__PURE__ */ jsx(Table.ColumnHeaderCell, { width: "25%", children: /* @__PURE__ */ jsx(
178
+ Translation,
179
+ {
180
+ defaultMessage: "Created",
181
+ id: "CXHhXd",
182
+ description: "Table column header for API key creation date"
183
+ }
184
+ ) }),
117
185
  /* @__PURE__ */ jsx(Table.ColumnHeaderCell, { width: "28px" })
118
186
  ] }) }),
119
187
  /* @__PURE__ */ jsx(Table.Body, { children: apiKeys.data.map((apiKey) => /* @__PURE__ */ jsx(ApiKeyRow, { apiKey }, apiKey.id)) })
@@ -129,7 +197,14 @@ function ApiKeysTable({
129
197
  type: "SET_PAGINATION",
130
198
  pagination: { after: apiKeys.listMetadata.after }
131
199
  }),
132
- children: "Previous"
200
+ children: /* @__PURE__ */ jsx(
201
+ Translation,
202
+ {
203
+ defaultMessage: "Previous",
204
+ id: "f7TUj0",
205
+ description: "Button to navigate to previous page of API keys"
206
+ }
207
+ )
133
208
  }
134
209
  ),
135
210
  /* @__PURE__ */ jsx(
@@ -142,7 +217,14 @@ function ApiKeysTable({
142
217
  type: "SET_PAGINATION",
143
218
  pagination: { before: apiKeys.listMetadata.before }
144
219
  }),
145
- children: "Next"
220
+ children: /* @__PURE__ */ jsx(
221
+ Translation,
222
+ {
223
+ defaultMessage: "Next",
224
+ id: "L2EBxV",
225
+ description: "Button to navigate to next page of API keys"
226
+ }
227
+ )
146
228
  }
147
229
  )
148
230
  ] })
@@ -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":[]}
@@ -9,6 +9,8 @@ import { CreateApiKeyButton } from "./create-api-key.js";
9
9
  import { getDomProps } from "../utils.js";
10
10
  import { ApiKeysSearchProvider } from "./api-keys-search-provider.js";
11
11
  import { ApiKeysTable } from "./api-keys-table.js";
12
+ import { Translation } from "../i18n/translation.js";
13
+ import { useTranslation } from "../i18n/use-translation.js";
12
14
  const ApiKeys = ({
13
15
  apiKeys,
14
16
  searchQuery,
@@ -23,6 +25,7 @@ const ApiKeys = ({
23
25
  ) });
24
26
  };
25
27
  const ApiKeysLoading = (props) => {
28
+ const translate = useTranslation();
26
29
  return /* @__PURE__ */ jsxs(
27
30
  Flex,
28
31
  {
@@ -37,11 +40,22 @@ const ApiKeysLoading = (props) => {
37
40
  {
38
41
  name: "api-keys-widget-search",
39
42
  style: { width: "390px" },
40
- placeholder: "Search by name",
43
+ placeholder: translate({
44
+ defaultMessage: "Search by name",
45
+ id: "VBESVz",
46
+ description: "Placeholder for API key search input in loading state"
47
+ }),
41
48
  children: /* @__PURE__ */ jsx(TextFieldSlot, { side: "left", children: /* @__PURE__ */ jsx(MagnifyingGlassIcon, { "aria-hidden": "true", height: "16", width: "16" }) })
42
49
  }
43
50
  ) }),
44
- /* @__PURE__ */ jsx(Skeleton, { children: /* @__PURE__ */ jsx(Button, { children: "Create API key" }) })
51
+ /* @__PURE__ */ jsx(Skeleton, { children: /* @__PURE__ */ jsx(Button, { children: /* @__PURE__ */ jsx(
52
+ Translation,
53
+ {
54
+ defaultMessage: "Create API key",
55
+ id: "eTEzjH",
56
+ description: "Button to create a new API key in loading state"
57
+ }
58
+ ) }) })
45
59
  ] }),
46
60
  /* @__PURE__ */ jsx(
47
61
  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":"AAuBI,cAqBE,YArBF;AAvBJ,SAAS,YAAY;AACrB,SAAS,QAAQ,UAAU,WAAW,qBAAqB;AAC3D,SAAS,oBAAoB;AAC7B,SAAS,kBAAkB;AAC3B,SAAS,2BAA2B;AACpC,SAAS,qBAAqB;AAC9B,SAAS,0BAA0B;AACnC,SAAS,mBAAwD;AAEjE,SAAS,6BAA6B;AACtC,SAAS,oBAAoB;AAO7B,MAAM,UAAkC,CAAC;AAAA,EACvC;AAAA,EACA;AAAA,EACA,GAAG;AACL,MAAM;AACJ,SAAO,QAAQ,KAAK,WAAW,KAAK,CAAC,cACnC,oBAAC,qBAAmB,GAAG,sBAAsB,YAAY,QAAQ,GAAG,IAEpE,oBAAC,yBACC;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,6BAAC,QAAK,SAAQ,WAAU,OAAM,UAC5B;AAAA,8BAAC,YACC;AAAA,YAAC;AAAA;AAAA,cACC,MAAK;AAAA,cACL,OAAO,EAAE,OAAO,QAAQ;AAAA,cACxB,aAAY;AAAA,cAEZ,8BAAC,iBAAc,MAAK,QAClB,8BAAC,uBAAoB,eAAY,QAAO,QAAO,MAAK,OAAM,MAAK,GACjE;AAAA;AAAA,UACF,GACF;AAAA,UACA,oBAAC,YACC,8BAAC,UAAO,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,oBAAC,gBAAa,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,oBAAC,sBAAmB;AAAA,MAC3B,GAAG;AAAA;AAAA,EACN;AAEJ;AAEA,SAAS,sBACP,OACA,UACA;AACA,SAAO,YAAY;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":"AAyBI,cAsBE,YAtBF;AAzBJ,SAAS,YAAY;AACrB,SAAS,QAAQ,UAAU,WAAW,qBAAqB;AAC3D,SAAS,oBAAoB;AAC7B,SAAS,kBAAkB;AAC3B,SAAS,2BAA2B;AACpC,SAAS,qBAAqB;AAC9B,SAAS,0BAA0B;AACnC,SAAS,mBAAwD;AAEjE,SAAS,6BAA6B;AACtC,SAAS,oBAAoB;AAC7B,SAAS,mBAAmB;AAC5B,SAAS,sBAAsB;AAO/B,MAAM,UAAkC,CAAC;AAAA,EACvC;AAAA,EACA;AAAA,EACA,GAAG;AACL,MAAM;AACJ,SAAO,QAAQ,KAAK,WAAW,KAAK,CAAC,cACnC,oBAAC,qBAAmB,GAAG,sBAAsB,YAAY,QAAQ,GAAG,IAEpE,oBAAC,yBACC;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACC,GAAG,sBAAsB,YAAY,QAAQ;AAAA;AAAA,EAChD,GACF;AAEJ;AAIA,MAAM,iBAAgD,CAAC,UAAU;AAC/D,QAAM,YAAY,eAAe;AACjC,SACE;AAAA,IAAC;AAAA;AAAA,MACC,WAAU;AAAA,MACV,OAAM;AAAA,MACN,KAAI;AAAA,MACH,GAAG,sBAAsB,WAAW,KAAK;AAAA,MAE1C;AAAA,6BAAC,QAAK,SAAQ,WAAU,OAAM,UAC5B;AAAA,8BAAC,YACC;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,8BAAC,iBAAc,MAAK,QAClB,8BAAC,uBAAoB,eAAY,QAAO,QAAO,MAAK,OAAM,MAAK,GACjE;AAAA;AAAA,UACF,GACF;AAAA,UACA,oBAAC,YACC,8BAAC,UACC;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,oBAAC,gBAAa,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,oBAAC,sBAAmB;AAAA,MAC3B,GAAG;AAAA;AAAA,EACN;AAEJ;AAEA,SAAS,sBACP,OACA,UACA;AACA,SAAO,YAAY;AAAA,IACjB,GAAG;AAAA,IACH,cAAc;AAAA,IACd,UAAU;AAAA,IACV,aAAa;AAAA,EACf,CAAC;AACH;","names":[]}
@@ -22,12 +22,13 @@ import {
22
22
  } from "@radix-ui/react-icons";
23
23
  import { CopyButton, CopyIconButton } from "../copy-button.js";
24
24
  import * as React from "react";
25
- import { pluralize } from "../utils.js";
26
25
  import {
27
26
  useListOrganizationApiKeyPermissions
28
27
  } from "../../api/endpoint.js";
29
28
  import { useCreateApiKey } from "../api/api-key.js";
30
29
  import { useApiKeysContext } from "./api-keys-context.js";
30
+ import { Translation } from "../i18n/translation.js";
31
+ import { useTranslation } from "../i18n/use-translation.js";
31
32
  function CreateApiKeyDialog() {
32
33
  const {
33
34
  state: { createDialogOpen, createdApiKey },
@@ -52,6 +53,7 @@ function CreateApiKeyDialog() {
52
53
  }
53
54
  function CreateApiKeyForm() {
54
55
  const { dispatch } = useApiKeysContext();
56
+ const translate = useTranslation();
55
57
  const [errors, setErrors] = React.useState({ name: false });
56
58
  const validate = (formData) => {
57
59
  const name = formData.get("name")?.toString() ?? "";
@@ -68,7 +70,14 @@ function CreateApiKeyForm() {
68
70
  } = useCreateApiKey();
69
71
  const permissions = useListOrganizationApiKeyPermissions({ limit: 100 });
70
72
  return /* @__PURE__ */ jsxs(Dialog.Content, { maxWidth: "529px", children: [
71
- /* @__PURE__ */ jsx(Dialog.Title, { size: "4", weight: "bold", children: "Create API key" }),
73
+ /* @__PURE__ */ jsx(Dialog.Title, { size: "4", weight: "bold", children: /* @__PURE__ */ jsx(
74
+ Translation,
75
+ {
76
+ defaultMessage: "Create API key",
77
+ id: "eUFRNS",
78
+ description: "Dialog title for creating a new API key"
79
+ }
80
+ ) }),
72
81
  /* @__PURE__ */ jsxs(
73
82
  Form.Root,
74
83
  {
@@ -98,25 +107,64 @@ function CreateApiKeyForm() {
98
107
  /* @__PURE__ */ jsxs(Flex, { direction: "column", align: "stretch", gap: "4", children: [
99
108
  error && /* @__PURE__ */ jsxs(Callout.Root, { color: "red", role: "alert", children: [
100
109
  /* @__PURE__ */ jsx(Callout.Icon, { children: /* @__PURE__ */ jsx(ExclamationTriangleIcon, {}) }),
101
- /* @__PURE__ */ jsx(Callout.Text, { children: "An error occurred while creating the API key." })
110
+ /* @__PURE__ */ jsx(Callout.Text, { children: /* @__PURE__ */ jsx(
111
+ Translation,
112
+ {
113
+ defaultMessage: "An error occurred while creating the API key.",
114
+ id: "0LyBVd",
115
+ description: "Error message when API key creation fails"
116
+ }
117
+ ) })
102
118
  ] }),
103
119
  /* @__PURE__ */ jsx(Form.Field, { name: "name", asChild: true, children: /* @__PURE__ */ jsxs(Flex, { direction: "column", align: "stretch", gap: "2", children: [
104
- /* @__PURE__ */ jsx(Form.Label, { asChild: true, children: /* @__PURE__ */ jsx(Label, { children: "Name" }) }),
120
+ /* @__PURE__ */ jsx(Form.Label, { asChild: true, children: /* @__PURE__ */ jsx(Label, { children: /* @__PURE__ */ jsx(
121
+ Translation,
122
+ {
123
+ defaultMessage: "Name",
124
+ id: "v0VmRy",
125
+ description: "Label for API key name input field"
126
+ }
127
+ ) }) }),
105
128
  /* @__PURE__ */ jsx(Form.Control, { asChild: true, children: /* @__PURE__ */ jsx(
106
129
  TextField,
107
130
  {
108
131
  "data-1p-ignore": true,
109
132
  autoComplete: "off",
110
- placeholder: "A descriptive name for the API key"
133
+ placeholder: translate({
134
+ defaultMessage: "A descriptive name for the API key",
135
+ id: "moyvr4",
136
+ description: "Placeholder for API key name input"
137
+ })
111
138
  }
112
139
  ) }),
113
- errors.name && /* @__PURE__ */ jsx(Form.Message, { asChild: true, children: /* @__PURE__ */ jsx(Text, { size: "2", color: "red", children: "The name is required" }) })
140
+ errors.name && /* @__PURE__ */ jsx(Form.Message, { asChild: true, children: /* @__PURE__ */ jsx(Text, { size: "2", color: "red", children: /* @__PURE__ */ jsx(
141
+ Translation,
142
+ {
143
+ defaultMessage: "The name is required",
144
+ id: "oF9d2V",
145
+ description: "Validation error when API key name is empty"
146
+ }
147
+ ) }) })
114
148
  ] }) }),
115
149
  permissions.isSuccess && permissions.data.data.length > 0 && /* @__PURE__ */ jsx(PermissionsField, { permissions: permissions.data.data })
116
150
  ] }),
117
151
  /* @__PURE__ */ jsxs(Flex, { align: "center", gap: "3", justify: "end", mt: "5", children: [
118
- /* @__PURE__ */ jsx(Dialog.Close, { children: /* @__PURE__ */ jsx(Button, { variant: "secondary", disabled: isPending || isSuccess, children: "Cancel" }) }),
119
- /* @__PURE__ */ jsx(Button, { type: "submit", loading: isPending || isSuccess, children: "Create API key" })
152
+ /* @__PURE__ */ jsx(Dialog.Close, { children: /* @__PURE__ */ jsx(Button, { variant: "secondary", disabled: isPending || isSuccess, children: /* @__PURE__ */ jsx(
153
+ Translation,
154
+ {
155
+ defaultMessage: "Cancel",
156
+ id: "AyVAAW",
157
+ description: "Button to cancel API key creation"
158
+ }
159
+ ) }) }),
160
+ /* @__PURE__ */ jsx(Button, { type: "submit", loading: isPending || isSuccess, children: /* @__PURE__ */ jsx(
161
+ Translation,
162
+ {
163
+ defaultMessage: "Create API key",
164
+ id: "d4BNWL",
165
+ description: "Button to submit and create the API key"
166
+ }
167
+ ) })
120
168
  ] })
121
169
  ]
122
170
  }
@@ -125,14 +173,42 @@ function CreateApiKeyForm() {
125
173
  }
126
174
  function SaveApiKeyContent({ apiKey }) {
127
175
  return /* @__PURE__ */ jsxs(Dialog.Content, { maxWidth: "529px", children: [
128
- /* @__PURE__ */ jsx(Dialog.Title, { size: "4", weight: "bold", children: "Save your key" }),
129
- /* @__PURE__ */ jsx(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." }),
176
+ /* @__PURE__ */ jsx(Dialog.Title, { size: "4", weight: "bold", children: /* @__PURE__ */ jsx(
177
+ Translation,
178
+ {
179
+ defaultMessage: "Save your key",
180
+ id: "wFFCij",
181
+ description: "Dialog title prompting user to save their API key"
182
+ }
183
+ ) }),
184
+ /* @__PURE__ */ jsx(Dialog.Description, { size: "2", children: /* @__PURE__ */ jsx(
185
+ Translation,
186
+ {
187
+ defaultMessage: "Please save this API key in a secure location. If you lose it, you'll need to generate a new one.",
188
+ id: "sy+2x7",
189
+ description: "Warning message about saving the API key"
190
+ }
191
+ ) }),
130
192
  /* @__PURE__ */ jsxs(Callout.Root, { mt: "5", mb: "4", children: [
131
193
  /* @__PURE__ */ jsx(Callout.Icon, { children: /* @__PURE__ */ jsx(InfoCircledIcon, {}) }),
132
- /* @__PURE__ */ jsx(Callout.Text, { children: "You won't be able to access the key again. Please copy it now." })
194
+ /* @__PURE__ */ jsx(Callout.Text, { children: /* @__PURE__ */ jsx(
195
+ Translation,
196
+ {
197
+ defaultMessage: "You won't be able to access the key again. Please copy it now.",
198
+ id: "EFAK/K",
199
+ description: "Callout warning that the key won't be accessible again"
200
+ }
201
+ ) })
133
202
  ] }),
134
203
  /* @__PURE__ */ jsx(TextField, { value: apiKey, readOnly: true, children: /* @__PURE__ */ jsx(TextFieldSlot, { side: "right", children: /* @__PURE__ */ jsx(CopyIconButton, { value: apiKey }) }) }),
135
- /* @__PURE__ */ jsx(Flex, { align: "center", gap: "3", justify: "end", mt: "5", children: /* @__PURE__ */ jsx(Dialog.Close, { children: /* @__PURE__ */ jsx(CopyButton, { value: apiKey, children: "Copy and close" }) }) })
204
+ /* @__PURE__ */ jsx(Flex, { align: "center", gap: "3", justify: "end", mt: "5", children: /* @__PURE__ */ jsx(Dialog.Close, { children: /* @__PURE__ */ jsx(CopyButton, { value: apiKey, children: /* @__PURE__ */ jsx(
205
+ Translation,
206
+ {
207
+ defaultMessage: "Copy and close",
208
+ id: "ViYtvQ",
209
+ description: "Button to copy API key and close dialog"
210
+ }
211
+ ) }) }) })
136
212
  ] });
137
213
  }
138
214
  function Permission({
@@ -177,6 +253,7 @@ function PermissionsField({
177
253
  const [selectedPermissions, setSelectedPermissions] = React.useState([]);
178
254
  const [filter, setFilter] = React.useState("");
179
255
  const fieldRef = React.useRef(null);
256
+ const translate = useTranslation();
180
257
  const filteredPermissions = React.useMemo(() => {
181
258
  return permissions.filter((p) => {
182
259
  return !filter.trim().length || p.description?.toLowerCase().match(filter.toLowerCase()) || p.name.toLowerCase().match(filter.toLowerCase()) || p.slug.toLowerCase().match(filter.toLowerCase());
@@ -194,8 +271,22 @@ function PermissionsField({
194
271
  };
195
272
  }, [filteredPermissions.length]);
196
273
  return /* @__PURE__ */ jsx(Form.Field, { name: "permissions", asChild: true, children: /* @__PURE__ */ jsxs(Flex, { direction: "column", align: "stretch", gap: "1", children: [
197
- /* @__PURE__ */ jsx(Form.Label, { asChild: true, children: /* @__PURE__ */ jsx(Label, { children: "Permissions" }) }),
198
- /* @__PURE__ */ jsx(Text, { size: "2", mb: "2", color: "gray", children: "Only enable the minimum permissions required for your use case." }),
274
+ /* @__PURE__ */ jsx(Form.Label, { asChild: true, children: /* @__PURE__ */ jsx(Label, { children: /* @__PURE__ */ jsx(
275
+ Translation,
276
+ {
277
+ defaultMessage: "Permissions",
278
+ id: "6YN1wO",
279
+ description: "Label for API key permissions field"
280
+ }
281
+ ) }) }),
282
+ /* @__PURE__ */ jsx(Text, { size: "2", mb: "2", color: "gray", children: /* @__PURE__ */ jsx(
283
+ Translation,
284
+ {
285
+ defaultMessage: "Only enable the minimum permissions required for your use case.",
286
+ id: "q2VEtG",
287
+ description: "Help text for API key permissions selection"
288
+ }
289
+ ) }),
199
290
  /* @__PURE__ */ jsxs(
200
291
  Flex,
201
292
  {
@@ -226,7 +317,11 @@ function PermissionsField({
226
317
  borderRadius: "var(--radius-3) var(--radius-3) 0 0",
227
318
  boxShadow: "none"
228
319
  },
229
- placeholder: "Search",
320
+ placeholder: translate({
321
+ defaultMessage: "Search",
322
+ id: "iyNcly",
323
+ description: "Placeholder for permissions search input"
324
+ }),
230
325
  children: /* @__PURE__ */ jsx(TextFieldSlot, { side: "left", px: "3", children: /* @__PURE__ */ jsx(MagnifyingGlassIcon, { "aria-hidden": "true", height: "16", width: "16" }) })
231
326
  }
232
327
  ),
@@ -301,14 +396,28 @@ function PermissionsField({
301
396
  }
302
397
  }
303
398
  ),
304
- /* @__PURE__ */ jsx(Text, { size: "2", align: "center", mb: "2", wrap: "balance", weight: "bold", children: "No permissions match your search" }),
399
+ /* @__PURE__ */ jsx(Text, { size: "2", align: "center", mb: "2", wrap: "balance", weight: "bold", children: /* @__PURE__ */ jsx(
400
+ Translation,
401
+ {
402
+ defaultMessage: "No permissions match your search",
403
+ id: "xjqT9f",
404
+ description: "Empty state message when no permissions match search"
405
+ }
406
+ ) }),
305
407
  /* @__PURE__ */ jsx(
306
408
  Button,
307
409
  {
308
410
  variant: "secondary",
309
411
  size: "1",
310
412
  onClick: () => setFilter(""),
311
- children: "Clear search"
413
+ children: /* @__PURE__ */ jsx(
414
+ Translation,
415
+ {
416
+ defaultMessage: "Clear search",
417
+ id: "YrMs63",
418
+ description: "Button to clear permissions search"
419
+ }
420
+ )
312
421
  }
313
422
  )
314
423
  ]
@@ -325,14 +434,50 @@ function SelectedPermissions({
325
434
  onToggle
326
435
  }) {
327
436
  return /* @__PURE__ */ jsxs(Flex, { align: "center", gap: "2", children: [
328
- /* @__PURE__ */ jsx(Text, { size: "1", style: { lineHeight: 1, color: "var(--gray-11)" }, children: selected === 0 ? "No permissions selected" : `${pluralize("permission", selected)} selected` }),
437
+ /* @__PURE__ */ jsx(Text, { size: "1", style: { lineHeight: 1, color: "var(--gray-11)" }, children: selected === 0 ? /* @__PURE__ */ jsx(
438
+ Translation,
439
+ {
440
+ defaultMessage: "No permissions selected",
441
+ id: "FqU9hv",
442
+ description: "Message when no permissions are selected"
443
+ }
444
+ ) : selected === 1 ? /* @__PURE__ */ jsx(
445
+ Translation,
446
+ {
447
+ defaultMessage: "1 permission selected",
448
+ id: "VouLgT",
449
+ description: "Message showing count of selected permissions"
450
+ }
451
+ ) : /* @__PURE__ */ jsx(
452
+ Translation,
453
+ {
454
+ defaultMessage: "{count} permissions selected",
455
+ id: "ZL90DI",
456
+ description: "Message showing count of selected permissions",
457
+ values: { count: selected }
458
+ }
459
+ ) }),
329
460
  /* @__PURE__ */ jsx(
330
461
  Text,
331
462
  {
332
463
  size: "1",
333
464
  onClick: onToggle,
334
465
  style: { cursor: "pointer", color: "var(--accent-10)" },
335
- children: total === selected ? "Deselect all" : "Select all"
466
+ children: total === selected ? /* @__PURE__ */ jsx(
467
+ Translation,
468
+ {
469
+ defaultMessage: "Deselect all",
470
+ id: "63f7SY",
471
+ description: "Button to deselect all permissions"
472
+ }
473
+ ) : /* @__PURE__ */ jsx(
474
+ Translation,
475
+ {
476
+ defaultMessage: "Select all",
477
+ id: "onTqlA",
478
+ description: "Button to select all permissions"
479
+ }
480
+ )
336
481
  }
337
482
  )
338
483
  ] });
@@ -344,7 +489,14 @@ function CreateApiKeyButton() {
344
489
  {
345
490
  variant: "secondary",
346
491
  onClick: () => dispatch({ type: "OPEN_CREATE_DIALOG" }),
347
- children: "Create API key"
492
+ children: /* @__PURE__ */ jsx(
493
+ Translation,
494
+ {
495
+ defaultMessage: "Create API key",
496
+ id: "vq5724",
497
+ description: "Button to open create API key dialog"
498
+ }
499
+ )
348
500
  }
349
501
  );
350
502
  }