@workos-inc/widgets 1.6.1 → 1.7.0-pre.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (281) hide show
  1. package/CHANGELOG.md +3 -1
  2. package/dist/cjs/admin-portal-domain-verification.client.d.cts +11 -0
  3. package/dist/cjs/admin-portal-sso-connection.client.d.cts +11 -0
  4. package/dist/cjs/alert-dialog-BlG3_awx.d.cts +25 -0
  5. package/dist/cjs/api-keys.client.d.cts +11 -0
  6. package/dist/cjs/dialog-C15qCLN3.d.cts +23 -0
  7. package/dist/cjs/dropdown-menu-BQ5LtvdR.d.cts +48 -0
  8. package/dist/cjs/index.d.cts +8 -0
  9. package/dist/cjs/lib/add-mfa-dialog.cjs +22 -14
  10. package/dist/cjs/lib/add-mfa-dialog.cjs.map +1 -1
  11. package/dist/cjs/lib/add-mfa-dialog.d.cts +2 -2
  12. package/dist/cjs/lib/admin-portal-domain-verification.cjs +6 -8
  13. package/dist/cjs/lib/admin-portal-domain-verification.cjs.map +1 -1
  14. package/dist/cjs/lib/admin-portal-domain-verification.d.cts +11 -0
  15. package/dist/cjs/lib/admin-portal-sso-connection.cjs +7 -8
  16. package/dist/cjs/lib/admin-portal-sso-connection.cjs.map +1 -1
  17. package/dist/cjs/lib/admin-portal-sso-connection.d.cts +11 -0
  18. package/dist/cjs/lib/api-keys/api-key-details-dialog.cjs +3 -3
  19. package/dist/cjs/lib/api-keys/api-key-details-dialog.cjs.map +1 -1
  20. package/dist/cjs/lib/api-keys/api-keys-search.cjs +2 -6
  21. package/dist/cjs/lib/api-keys/api-keys-search.cjs.map +1 -1
  22. package/dist/cjs/lib/api-keys/api-keys-table.cjs +18 -19
  23. package/dist/cjs/lib/api-keys/api-keys-table.cjs.map +1 -1
  24. package/dist/cjs/lib/api-keys/api-keys.cjs +2 -2
  25. package/dist/cjs/lib/api-keys/api-keys.cjs.map +1 -1
  26. package/dist/cjs/lib/api-keys/api-keys.d.cts +12 -0
  27. package/dist/cjs/lib/api-keys/create-api-key.cjs +20 -14
  28. package/dist/cjs/lib/api-keys/create-api-key.cjs.map +1 -1
  29. package/dist/cjs/lib/api-keys/revoke-api-key-dialog.cjs +7 -7
  30. package/dist/cjs/lib/api-keys/revoke-api-key-dialog.cjs.map +1 -1
  31. package/dist/cjs/lib/api-keys/skeleton-table.cjs +3 -2
  32. package/dist/cjs/lib/api-keys/skeleton-table.cjs.map +1 -1
  33. package/dist/cjs/lib/change-password-dialog.cjs +11 -9
  34. package/dist/cjs/lib/change-password-dialog.cjs.map +1 -1
  35. package/dist/cjs/lib/change-password-dialog.d.cts +2 -2
  36. package/dist/cjs/lib/copy-button.cjs +51 -29
  37. package/dist/cjs/lib/copy-button.cjs.map +1 -1
  38. package/dist/cjs/lib/copy-button.d.cts +22 -4
  39. package/dist/cjs/lib/delete-domain-dialog.cjs +8 -7
  40. package/dist/cjs/lib/delete-domain-dialog.cjs.map +1 -1
  41. package/dist/cjs/lib/delete-user-dialog.cjs +15 -7
  42. package/dist/cjs/lib/delete-user-dialog.cjs.map +1 -1
  43. package/dist/cjs/lib/delete-user-dialog.d.cts +2 -2
  44. package/dist/cjs/lib/domain-actions.cjs +8 -8
  45. package/dist/cjs/lib/domain-actions.cjs.map +1 -1
  46. package/dist/cjs/lib/edit-user-profile-dialog.cjs +10 -9
  47. package/dist/cjs/lib/edit-user-profile-dialog.cjs.map +1 -1
  48. package/dist/cjs/lib/edit-user-profile-dialog.d.cts +2 -2
  49. package/dist/cjs/lib/edit-user-role-dialog.cjs +15 -15
  50. package/dist/cjs/lib/edit-user-role-dialog.cjs.map +1 -1
  51. package/dist/cjs/lib/edit-user-role-dialog.d.cts +2 -2
  52. package/dist/cjs/lib/elements/alert-dialog.cjs +76 -0
  53. package/dist/cjs/lib/elements/alert-dialog.cjs.map +1 -0
  54. package/dist/cjs/lib/elements/alert-dialog.d.cts +3 -0
  55. package/dist/cjs/lib/elements/dialog.cjs +74 -0
  56. package/dist/cjs/lib/elements/dialog.cjs.map +1 -0
  57. package/dist/cjs/lib/elements/dialog.d.cts +3 -0
  58. package/dist/cjs/lib/elements/dropdown-menu.cjs +162 -0
  59. package/dist/cjs/lib/elements/dropdown-menu.cjs.map +1 -0
  60. package/dist/cjs/lib/elements/dropdown-menu.d.cts +3 -0
  61. package/dist/cjs/lib/elements/select.cjs +112 -0
  62. package/dist/cjs/lib/elements/select.cjs.map +1 -0
  63. package/dist/cjs/lib/elements/select.d.cts +4 -0
  64. package/dist/cjs/lib/elements/utils.cjs +54 -0
  65. package/dist/cjs/lib/elements/utils.cjs.map +1 -0
  66. package/dist/cjs/lib/elements/utils.d.cts +15 -0
  67. package/dist/cjs/lib/elements.cjs +73 -219
  68. package/dist/cjs/lib/elements.cjs.map +1 -1
  69. package/dist/cjs/lib/elements.d.cts +16 -13
  70. package/dist/cjs/lib/elevated-access.cjs +18 -10
  71. package/dist/cjs/lib/elevated-access.cjs.map +1 -1
  72. package/dist/cjs/lib/empty-state.d.cts +12 -0
  73. package/dist/cjs/lib/invite-user-dialog.cjs +13 -12
  74. package/dist/cjs/lib/invite-user-dialog.cjs.map +1 -1
  75. package/dist/cjs/lib/logout-all-sessions-dialog.cjs +7 -6
  76. package/dist/cjs/lib/logout-all-sessions-dialog.cjs.map +1 -1
  77. package/dist/cjs/lib/logout-all-sessions-dialog.d.cts +2 -2
  78. package/dist/cjs/lib/logout-dialog.cjs +7 -6
  79. package/dist/cjs/lib/logout-dialog.cjs.map +1 -1
  80. package/dist/cjs/lib/logout-dialog.d.cts +2 -2
  81. package/dist/cjs/lib/organization-switcher.cjs +38 -20
  82. package/dist/cjs/lib/organization-switcher.cjs.map +1 -1
  83. package/dist/cjs/lib/organization-switcher.d.cts +16 -2
  84. package/dist/cjs/lib/otp-input.d.cts +8 -0
  85. package/dist/cjs/lib/pipes.cjs +31 -42
  86. package/dist/cjs/lib/pipes.cjs.map +1 -1
  87. package/dist/cjs/lib/pipes.d.cts +12 -0
  88. package/dist/cjs/lib/resend-invite-dialog.cjs +23 -13
  89. package/dist/cjs/lib/resend-invite-dialog.cjs.map +1 -1
  90. package/dist/cjs/lib/resend-invite-dialog.d.cts +2 -2
  91. package/dist/cjs/lib/reset-mfa-dialog.cjs +9 -8
  92. package/dist/cjs/lib/reset-mfa-dialog.cjs.map +1 -1
  93. package/dist/cjs/lib/reset-mfa-dialog.d.cts +2 -2
  94. package/dist/cjs/lib/revoke-invite-dialog.cjs +17 -8
  95. package/dist/cjs/lib/revoke-invite-dialog.cjs.map +1 -1
  96. package/dist/cjs/lib/revoke-invite-dialog.d.cts +2 -2
  97. package/dist/cjs/lib/save-button.cjs +3 -2
  98. package/dist/cjs/lib/save-button.cjs.map +1 -1
  99. package/dist/cjs/lib/save-button.d.cts +12 -1
  100. package/dist/cjs/lib/set-password-dialog.cjs +11 -9
  101. package/dist/cjs/lib/set-password-dialog.cjs.map +1 -1
  102. package/dist/cjs/lib/set-password-dialog.d.cts +2 -2
  103. package/dist/cjs/lib/user-actions-dropdown.cjs +9 -8
  104. package/dist/cjs/lib/user-actions-dropdown.cjs.map +1 -1
  105. package/dist/cjs/lib/user-profile.cjs +1 -1
  106. package/dist/cjs/lib/user-profile.cjs.map +1 -1
  107. package/dist/cjs/lib/user-profile.d.cts +11 -0
  108. package/dist/cjs/lib/user-security.cjs +3 -3
  109. package/dist/cjs/lib/user-security.cjs.map +1 -1
  110. package/dist/cjs/lib/user-security.d.cts +12 -0
  111. package/dist/cjs/lib/user-sessions.cjs +3 -11
  112. package/dist/cjs/lib/user-sessions.cjs.map +1 -1
  113. package/dist/cjs/lib/user-sessions.d.cts +12 -0
  114. package/dist/cjs/lib/users-filter.cjs +5 -6
  115. package/dist/cjs/lib/users-filter.cjs.map +1 -1
  116. package/dist/cjs/lib/users-filter.d.cts +2 -2
  117. package/dist/cjs/lib/users-management.cjs +22 -34
  118. package/dist/cjs/lib/users-management.cjs.map +1 -1
  119. package/dist/cjs/lib/users-management.d.cts +11 -0
  120. package/dist/cjs/lib/users-search.cjs +2 -6
  121. package/dist/cjs/lib/users-search.cjs.map +1 -1
  122. package/dist/cjs/lib/utils.cjs +25 -2
  123. package/dist/cjs/lib/utils.cjs.map +1 -1
  124. package/dist/cjs/lib/utils.d.cts +17 -3
  125. package/dist/cjs/lib/view-dns-record-dialog.cjs +9 -8
  126. package/dist/cjs/lib/view-dns-record-dialog.cjs.map +1 -1
  127. package/dist/cjs/lib/widgets-context.d.cts +8 -0
  128. package/dist/cjs/organization-switcher.client.cjs +33 -5
  129. package/dist/cjs/organization-switcher.client.cjs.map +1 -1
  130. package/dist/cjs/organization-switcher.client.d.cts +11 -0
  131. package/dist/cjs/pipes.client.d.cts +11 -0
  132. package/dist/cjs/select-KR89Qnvm.d.cts +30 -0
  133. package/dist/cjs/user-profile.client.d.cts +11 -0
  134. package/dist/cjs/user-security.client.d.cts +11 -0
  135. package/dist/cjs/user-sessions.client.d.cts +11 -0
  136. package/dist/cjs/users-management.client.d.cts +11 -0
  137. package/dist/cjs/utils.cjs +59 -0
  138. package/dist/cjs/utils.cjs.map +1 -0
  139. package/dist/cjs/utils.d.cts +3 -0
  140. package/dist/cjs/workos-widgets.client.d.cts +8 -0
  141. package/dist/css/lib/provider-icon.css +6 -0
  142. package/dist/esm/admin-portal-domain-verification.client.d.ts +11 -0
  143. package/dist/esm/admin-portal-sso-connection.client.d.ts +11 -0
  144. package/dist/esm/alert-dialog-BlG3_awx.d.ts +25 -0
  145. package/dist/esm/api-keys.client.d.ts +11 -0
  146. package/dist/esm/dialog-C15qCLN3.d.ts +23 -0
  147. package/dist/esm/dropdown-menu-BQ5LtvdR.d.ts +48 -0
  148. package/dist/esm/index.d.ts +8 -0
  149. package/dist/esm/lib/add-mfa-dialog.d.ts +2 -2
  150. package/dist/esm/lib/add-mfa-dialog.js +16 -9
  151. package/dist/esm/lib/add-mfa-dialog.js.map +1 -1
  152. package/dist/esm/lib/admin-portal-domain-verification.d.ts +11 -0
  153. package/dist/esm/lib/admin-portal-domain-verification.js +6 -8
  154. package/dist/esm/lib/admin-portal-domain-verification.js.map +1 -1
  155. package/dist/esm/lib/admin-portal-sso-connection.d.ts +11 -0
  156. package/dist/esm/lib/admin-portal-sso-connection.js +8 -9
  157. package/dist/esm/lib/admin-portal-sso-connection.js.map +1 -1
  158. package/dist/esm/lib/api-keys/api-key-details-dialog.js +3 -3
  159. package/dist/esm/lib/api-keys/api-key-details-dialog.js.map +1 -1
  160. package/dist/esm/lib/api-keys/api-keys-search.js +2 -6
  161. package/dist/esm/lib/api-keys/api-keys-search.js.map +1 -1
  162. package/dist/esm/lib/api-keys/api-keys-table.js +18 -32
  163. package/dist/esm/lib/api-keys/api-keys-table.js.map +1 -1
  164. package/dist/esm/lib/api-keys/api-keys.d.ts +12 -0
  165. package/dist/esm/lib/api-keys/api-keys.js +2 -2
  166. package/dist/esm/lib/api-keys/api-keys.js.map +1 -1
  167. package/dist/esm/lib/api-keys/create-api-key.js +17 -14
  168. package/dist/esm/lib/api-keys/create-api-key.js.map +1 -1
  169. package/dist/esm/lib/api-keys/revoke-api-key-dialog.js +4 -4
  170. package/dist/esm/lib/api-keys/revoke-api-key-dialog.js.map +1 -1
  171. package/dist/esm/lib/api-keys/skeleton-table.js +2 -1
  172. package/dist/esm/lib/api-keys/skeleton-table.js.map +1 -1
  173. package/dist/esm/lib/change-password-dialog.d.ts +2 -2
  174. package/dist/esm/lib/change-password-dialog.js +8 -12
  175. package/dist/esm/lib/change-password-dialog.js.map +1 -1
  176. package/dist/esm/lib/copy-button.d.ts +22 -4
  177. package/dist/esm/lib/copy-button.js +49 -28
  178. package/dist/esm/lib/copy-button.js.map +1 -1
  179. package/dist/esm/lib/delete-domain-dialog.js +4 -3
  180. package/dist/esm/lib/delete-domain-dialog.js.map +1 -1
  181. package/dist/esm/lib/delete-user-dialog.d.ts +2 -2
  182. package/dist/esm/lib/delete-user-dialog.js +13 -15
  183. package/dist/esm/lib/delete-user-dialog.js.map +1 -1
  184. package/dist/esm/lib/domain-actions.js +4 -4
  185. package/dist/esm/lib/domain-actions.js.map +1 -1
  186. package/dist/esm/lib/edit-user-profile-dialog.d.ts +2 -2
  187. package/dist/esm/lib/edit-user-profile-dialog.js +7 -12
  188. package/dist/esm/lib/edit-user-profile-dialog.js.map +1 -1
  189. package/dist/esm/lib/edit-user-role-dialog.d.ts +2 -2
  190. package/dist/esm/lib/edit-user-role-dialog.js +9 -19
  191. package/dist/esm/lib/edit-user-role-dialog.js.map +1 -1
  192. package/dist/esm/lib/elements/alert-dialog.d.ts +3 -0
  193. package/dist/esm/lib/elements/alert-dialog.js +45 -0
  194. package/dist/esm/lib/elements/alert-dialog.js.map +1 -0
  195. package/dist/esm/lib/elements/dialog.d.ts +3 -0
  196. package/dist/esm/lib/elements/dialog.js +43 -0
  197. package/dist/esm/lib/elements/dialog.js.map +1 -0
  198. package/dist/esm/lib/elements/dropdown-menu.d.ts +3 -0
  199. package/dist/esm/lib/elements/dropdown-menu.js +131 -0
  200. package/dist/esm/lib/elements/dropdown-menu.js.map +1 -0
  201. package/dist/esm/lib/elements/select.d.ts +4 -0
  202. package/dist/esm/lib/elements/select.js +77 -0
  203. package/dist/esm/lib/elements/select.js.map +1 -0
  204. package/dist/esm/lib/elements/utils.d.ts +15 -0
  205. package/dist/esm/lib/elements/utils.js +20 -0
  206. package/dist/esm/lib/elements/utils.js.map +1 -0
  207. package/dist/esm/lib/elements.d.ts +16 -13
  208. package/dist/esm/lib/elements.js +71 -215
  209. package/dist/esm/lib/elements.js.map +1 -1
  210. package/dist/esm/lib/elevated-access.js +14 -6
  211. package/dist/esm/lib/elevated-access.js.map +1 -1
  212. package/dist/esm/lib/empty-state.d.ts +12 -0
  213. package/dist/esm/lib/invite-user-dialog.js +10 -24
  214. package/dist/esm/lib/invite-user-dialog.js.map +1 -1
  215. package/dist/esm/lib/logout-all-sessions-dialog.d.ts +2 -2
  216. package/dist/esm/lib/logout-all-sessions-dialog.js +6 -9
  217. package/dist/esm/lib/logout-all-sessions-dialog.js.map +1 -1
  218. package/dist/esm/lib/logout-dialog.d.ts +2 -2
  219. package/dist/esm/lib/logout-dialog.js +6 -9
  220. package/dist/esm/lib/logout-dialog.js.map +1 -1
  221. package/dist/esm/lib/organization-switcher.d.ts +16 -2
  222. package/dist/esm/lib/organization-switcher.js +33 -13
  223. package/dist/esm/lib/organization-switcher.js.map +1 -1
  224. package/dist/esm/lib/otp-input.d.ts +8 -0
  225. package/dist/esm/lib/pipes.d.ts +12 -0
  226. package/dist/esm/lib/pipes.js +27 -47
  227. package/dist/esm/lib/pipes.js.map +1 -1
  228. package/dist/esm/lib/resend-invite-dialog.d.ts +2 -2
  229. package/dist/esm/lib/resend-invite-dialog.js +17 -20
  230. package/dist/esm/lib/resend-invite-dialog.js.map +1 -1
  231. package/dist/esm/lib/reset-mfa-dialog.d.ts +2 -2
  232. package/dist/esm/lib/reset-mfa-dialog.js +6 -9
  233. package/dist/esm/lib/reset-mfa-dialog.js.map +1 -1
  234. package/dist/esm/lib/revoke-invite-dialog.d.ts +2 -2
  235. package/dist/esm/lib/revoke-invite-dialog.js +14 -15
  236. package/dist/esm/lib/revoke-invite-dialog.js.map +1 -1
  237. package/dist/esm/lib/save-button.d.ts +12 -1
  238. package/dist/esm/lib/save-button.js +4 -9
  239. package/dist/esm/lib/save-button.js.map +1 -1
  240. package/dist/esm/lib/set-password-dialog.d.ts +2 -2
  241. package/dist/esm/lib/set-password-dialog.js +8 -12
  242. package/dist/esm/lib/set-password-dialog.js.map +1 -1
  243. package/dist/esm/lib/user-actions-dropdown.js +8 -11
  244. package/dist/esm/lib/user-actions-dropdown.js.map +1 -1
  245. package/dist/esm/lib/user-profile.d.ts +11 -0
  246. package/dist/esm/lib/user-profile.js +2 -2
  247. package/dist/esm/lib/user-profile.js.map +1 -1
  248. package/dist/esm/lib/user-security.d.ts +12 -0
  249. package/dist/esm/lib/user-security.js +4 -4
  250. package/dist/esm/lib/user-security.js.map +1 -1
  251. package/dist/esm/lib/user-sessions.d.ts +12 -0
  252. package/dist/esm/lib/user-sessions.js +5 -13
  253. package/dist/esm/lib/user-sessions.js.map +1 -1
  254. package/dist/esm/lib/users-filter.d.ts +2 -2
  255. package/dist/esm/lib/users-filter.js +5 -6
  256. package/dist/esm/lib/users-filter.js.map +1 -1
  257. package/dist/esm/lib/users-management.d.ts +11 -0
  258. package/dist/esm/lib/users-management.js +23 -39
  259. package/dist/esm/lib/users-management.js.map +1 -1
  260. package/dist/esm/lib/users-search.js +2 -6
  261. package/dist/esm/lib/users-search.js.map +1 -1
  262. package/dist/esm/lib/utils.d.ts +17 -3
  263. package/dist/esm/lib/utils.js +24 -2
  264. package/dist/esm/lib/utils.js.map +1 -1
  265. package/dist/esm/lib/view-dns-record-dialog.js +7 -17
  266. package/dist/esm/lib/view-dns-record-dialog.js.map +1 -1
  267. package/dist/esm/lib/widgets-context.d.ts +8 -0
  268. package/dist/esm/organization-switcher.client.d.ts +11 -0
  269. package/dist/esm/organization-switcher.client.js +33 -5
  270. package/dist/esm/organization-switcher.client.js.map +1 -1
  271. package/dist/esm/pipes.client.d.ts +11 -0
  272. package/dist/esm/select-KR89Qnvm.d.ts +30 -0
  273. package/dist/esm/user-profile.client.d.ts +11 -0
  274. package/dist/esm/user-security.client.d.ts +11 -0
  275. package/dist/esm/user-sessions.client.d.ts +11 -0
  276. package/dist/esm/users-management.client.d.ts +11 -0
  277. package/dist/esm/utils.d.ts +3 -0
  278. package/dist/esm/utils.js +25 -0
  279. package/dist/esm/utils.js.map +1 -0
  280. package/dist/esm/workos-widgets.client.d.ts +8 -0
  281. package/package.json +11 -1
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/lib/save-button.tsx"],"sourcesContent":["import {\n ButtonProps,\n Flex,\n Slot,\n Slottable,\n Spinner,\n Text,\n} from \"@radix-ui/themes\";\nimport { CheckIcon } from \"@radix-ui/react-icons\";\nimport { useEffect, useRef, useState } from \"react\";\nimport { namespaceClassNames } from \"./utils.js\";\n\nconst DONE_TIMEOUT_MS = 1500;\nconst SAVING_TIMEOUT_MS = 600;\n\ninterface SaveButtonProps extends ButtonProps {\n asChild?: boolean;\n children: React.ReactNode;\n loading?: boolean;\n done?: boolean;\n onDone?: () => void;\n}\n\nexport function SaveButton({\n asChild = false,\n children,\n loading,\n done,\n onDone,\n ...props\n}: SaveButtonProps) {\n const [state, setState] = useState<\"idle\" | \"loading\" | \"done\">(\n loading ? \"loading\" : done ? \"done\" : \"idle\",\n );\n const loadingStartTime = useRef<number | null>(null);\n const Button = asChild ? Slot : \"button\";\n\n useEffect(() => {\n if (loading) {\n // FIXME: This should be refactored\n // eslint-disable-next-line react-hooks/set-state-in-effect\n setState(\"loading\");\n loadingStartTime.current = Date.now();\n } else if (done) {\n const currentTime = Date.now();\n const loadingDuration = loadingStartTime.current\n ? currentTime - loadingStartTime.current\n : 0;\n\n // If loading lasted less than 500 ms, wait for the remaining time\n const remainingDelay = Math.max(0, SAVING_TIMEOUT_MS - loadingDuration);\n\n let doneTimer: number | null = null;\n const savedTimer = window.setTimeout(() => {\n setState(\"done\");\n\n doneTimer = window.setTimeout(() => {\n onDone?.();\n }, DONE_TIMEOUT_MS);\n }, remainingDelay);\n\n return () => {\n window.clearTimeout(savedTimer);\n if (doneTimer !== null) {\n window.clearTimeout(doneTimer);\n }\n };\n } else if (!loading && !done) {\n setState(\"idle\");\n }\n }, [loading, done, onDone]);\n\n return (\n <Button\n {...props}\n className={namespaceClassNames(\"save-button\")}\n data-save-state={state}\n >\n <Slottable>{children}</Slottable>\n\n {state === \"loading\" && (\n <Flex\n as=\"span\"\n align=\"center\"\n justify=\"center\"\n position=\"absolute\"\n inset=\"0\"\n >\n <Spinner size=\"1\" />\n </Flex>\n )}\n\n {state === \"done\" && (\n <Flex\n as=\"span\"\n align=\"center\"\n justify=\"center\"\n position=\"absolute\"\n inset=\"0\"\n gap=\"1\"\n >\n <CheckIcon\n width=\"18px\"\n height=\"18px\"\n style={{ marginLeft: \"-4px\" }}\n className={namespaceClassNames(\"save-button__done-icon\")}\n />\n <Text className={namespaceClassNames(\"save-button__done-text\")}>\n Done\n </Text>\n </Flex>\n )}\n </Button>\n );\n}\n"],"mappings":"AA8EM,cAeE,YAfF;AA9EN;AAAA,EAEE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,iBAAiB;AAC1B,SAAS,WAAW,QAAQ,gBAAgB;AAC5C,SAAS,2BAA2B;AAEpC,MAAM,kBAAkB;AACxB,MAAM,oBAAoB;AAUnB,SAAS,WAAW;AAAA,EACzB,UAAU;AAAA,EACV;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,GAAG;AACL,GAAoB;AAClB,QAAM,CAAC,OAAO,QAAQ,IAAI;AAAA,IACxB,UAAU,YAAY,OAAO,SAAS;AAAA,EACxC;AACA,QAAM,mBAAmB,OAAsB,IAAI;AACnD,QAAM,SAAS,UAAU,OAAO;AAEhC,YAAU,MAAM;AACd,QAAI,SAAS;AAGX,eAAS,SAAS;AAClB,uBAAiB,UAAU,KAAK,IAAI;AAAA,IACtC,WAAW,MAAM;AACf,YAAM,cAAc,KAAK,IAAI;AAC7B,YAAM,kBAAkB,iBAAiB,UACrC,cAAc,iBAAiB,UAC/B;AAGJ,YAAM,iBAAiB,KAAK,IAAI,GAAG,oBAAoB,eAAe;AAEtE,UAAI,YAA2B;AAC/B,YAAM,aAAa,OAAO,WAAW,MAAM;AACzC,iBAAS,MAAM;AAEf,oBAAY,OAAO,WAAW,MAAM;AAClC,mBAAS;AAAA,QACX,GAAG,eAAe;AAAA,MACpB,GAAG,cAAc;AAEjB,aAAO,MAAM;AACX,eAAO,aAAa,UAAU;AAC9B,YAAI,cAAc,MAAM;AACtB,iBAAO,aAAa,SAAS;AAAA,QAC/B;AAAA,MACF;AAAA,IACF,WAAW,CAAC,WAAW,CAAC,MAAM;AAC5B,eAAS,MAAM;AAAA,IACjB;AAAA,EACF,GAAG,CAAC,SAAS,MAAM,MAAM,CAAC;AAE1B,SACE;AAAA,IAAC;AAAA;AAAA,MACE,GAAG;AAAA,MACJ,WAAW,oBAAoB,aAAa;AAAA,MAC5C,mBAAiB;AAAA,MAEjB;AAAA,4BAAC,aAAW,UAAS;AAAA,QAEpB,UAAU,aACT;AAAA,UAAC;AAAA;AAAA,YACC,IAAG;AAAA,YACH,OAAM;AAAA,YACN,SAAQ;AAAA,YACR,UAAS;AAAA,YACT,OAAM;AAAA,YAEN,8BAAC,WAAQ,MAAK,KAAI;AAAA;AAAA,QACpB;AAAA,QAGD,UAAU,UACT;AAAA,UAAC;AAAA;AAAA,YACC,IAAG;AAAA,YACH,OAAM;AAAA,YACN,SAAQ;AAAA,YACR,UAAS;AAAA,YACT,OAAM;AAAA,YACN,KAAI;AAAA,YAEJ;AAAA;AAAA,gBAAC;AAAA;AAAA,kBACC,OAAM;AAAA,kBACN,QAAO;AAAA,kBACP,OAAO,EAAE,YAAY,OAAO;AAAA,kBAC5B,WAAW,oBAAoB,wBAAwB;AAAA;AAAA,cACzD;AAAA,cACA,oBAAC,QAAK,WAAW,oBAAoB,wBAAwB,GAAG,kBAEhE;AAAA;AAAA;AAAA,QACF;AAAA;AAAA;AAAA,EAEJ;AAEJ;","names":[]}
1
+ {"version":3,"sources":["../../../src/lib/save-button.tsx"],"sourcesContent":["import { Flex, Slot, Slottable, Spinner, Text } from \"@radix-ui/themes\";\nimport { CheckIcon } from \"@radix-ui/react-icons\";\nimport { useEffect, useRef, useState } from \"react\";\nimport { namespaceClassNames } from \"./utils.js\";\nimport { Button, type ButtonProps } from \"./elements.js\";\n\nconst DONE_TIMEOUT_MS = 1500;\nconst SAVING_TIMEOUT_MS = 600;\n\ninterface SaveButtonProps extends ButtonProps {\n asChild?: boolean;\n children: React.ReactNode;\n loading?: boolean;\n done?: boolean;\n onDone?: () => void;\n}\n\nexport function SaveButton({\n asChild = false,\n children,\n loading,\n done,\n onDone,\n ...props\n}: SaveButtonProps) {\n const [state, setState] = useState<\"idle\" | \"loading\" | \"done\">(\n loading ? \"loading\" : done ? \"done\" : \"idle\",\n );\n const loadingStartTime = useRef<number | null>(null);\n const ButtonComponent = asChild ? Slot : Button;\n\n useEffect(() => {\n if (loading) {\n // FIXME: This should be refactored\n // eslint-disable-next-line react-hooks/set-state-in-effect\n setState(\"loading\");\n loadingStartTime.current = Date.now();\n } else if (done) {\n const currentTime = Date.now();\n const loadingDuration = loadingStartTime.current\n ? currentTime - loadingStartTime.current\n : 0;\n\n // If loading lasted less than 500 ms, wait for the remaining time\n const remainingDelay = Math.max(0, SAVING_TIMEOUT_MS - loadingDuration);\n\n let doneTimer: number | null = null;\n const savedTimer = window.setTimeout(() => {\n setState(\"done\");\n\n doneTimer = window.setTimeout(() => {\n onDone?.();\n }, DONE_TIMEOUT_MS);\n }, remainingDelay);\n\n return () => {\n window.clearTimeout(savedTimer);\n if (doneTimer !== null) {\n window.clearTimeout(doneTimer);\n }\n };\n } else if (!loading && !done) {\n setState(\"idle\");\n }\n }, [loading, done, onDone]);\n\n return (\n <ButtonComponent\n {...props}\n className={namespaceClassNames(\"save-button\")}\n data-save-state={state}\n >\n <Slottable>{children}</Slottable>\n {state === \"loading\" && (\n <Flex\n as=\"span\"\n align=\"center\"\n justify=\"center\"\n position=\"absolute\"\n inset=\"0\"\n >\n <Spinner size=\"1\" />\n </Flex>\n )}\n\n {state === \"done\" && (\n <Flex\n as=\"span\"\n align=\"center\"\n justify=\"center\"\n position=\"absolute\"\n inset=\"0\"\n gap=\"1\"\n >\n <CheckIcon\n width=\"18px\"\n height=\"18px\"\n style={{ marginLeft: \"-4px\" }}\n className={namespaceClassNames(\"save-button__done-icon\")}\n />\n <Text className={namespaceClassNames(\"save-button__done-text\")}>\n Done\n </Text>\n </Flex>\n )}\n </ButtonComponent>\n );\n}\n"],"mappings":"AAwEM,cAcE,YAdF;AAxEN,SAAS,MAAM,MAAM,WAAW,SAAS,YAAY;AACrD,SAAS,iBAAiB;AAC1B,SAAS,WAAW,QAAQ,gBAAgB;AAC5C,SAAS,2BAA2B;AACpC,SAAS,cAAgC;AAEzC,MAAM,kBAAkB;AACxB,MAAM,oBAAoB;AAUnB,SAAS,WAAW;AAAA,EACzB,UAAU;AAAA,EACV;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,GAAG;AACL,GAAoB;AAClB,QAAM,CAAC,OAAO,QAAQ,IAAI;AAAA,IACxB,UAAU,YAAY,OAAO,SAAS;AAAA,EACxC;AACA,QAAM,mBAAmB,OAAsB,IAAI;AACnD,QAAM,kBAAkB,UAAU,OAAO;AAEzC,YAAU,MAAM;AACd,QAAI,SAAS;AAGX,eAAS,SAAS;AAClB,uBAAiB,UAAU,KAAK,IAAI;AAAA,IACtC,WAAW,MAAM;AACf,YAAM,cAAc,KAAK,IAAI;AAC7B,YAAM,kBAAkB,iBAAiB,UACrC,cAAc,iBAAiB,UAC/B;AAGJ,YAAM,iBAAiB,KAAK,IAAI,GAAG,oBAAoB,eAAe;AAEtE,UAAI,YAA2B;AAC/B,YAAM,aAAa,OAAO,WAAW,MAAM;AACzC,iBAAS,MAAM;AAEf,oBAAY,OAAO,WAAW,MAAM;AAClC,mBAAS;AAAA,QACX,GAAG,eAAe;AAAA,MACpB,GAAG,cAAc;AAEjB,aAAO,MAAM;AACX,eAAO,aAAa,UAAU;AAC9B,YAAI,cAAc,MAAM;AACtB,iBAAO,aAAa,SAAS;AAAA,QAC/B;AAAA,MACF;AAAA,IACF,WAAW,CAAC,WAAW,CAAC,MAAM;AAC5B,eAAS,MAAM;AAAA,IACjB;AAAA,EACF,GAAG,CAAC,SAAS,MAAM,MAAM,CAAC;AAE1B,SACE;AAAA,IAAC;AAAA;AAAA,MACE,GAAG;AAAA,MACJ,WAAW,oBAAoB,aAAa;AAAA,MAC5C,mBAAiB;AAAA,MAEjB;AAAA,4BAAC,aAAW,UAAS;AAAA,QACpB,UAAU,aACT;AAAA,UAAC;AAAA;AAAA,YACC,IAAG;AAAA,YACH,OAAM;AAAA,YACN,SAAQ;AAAA,YACR,UAAS;AAAA,YACT,OAAM;AAAA,YAEN,8BAAC,WAAQ,MAAK,KAAI;AAAA;AAAA,QACpB;AAAA,QAGD,UAAU,UACT;AAAA,UAAC;AAAA;AAAA,YACC,IAAG;AAAA,YACH,OAAM;AAAA,YACN,SAAQ;AAAA,YACR,UAAS;AAAA,YACT,OAAM;AAAA,YACN,KAAI;AAAA,YAEJ;AAAA;AAAA,gBAAC;AAAA;AAAA,kBACC,OAAM;AAAA,kBACN,QAAO;AAAA,kBACP,OAAO,EAAE,YAAY,OAAO;AAAA,kBAC5B,WAAW,oBAAoB,wBAAwB;AAAA;AAAA,cACzD;AAAA,cACA,oBAAC,QAAK,WAAW,oBAAoB,wBAAwB,GAAG,kBAEhE;AAAA;AAAA;AAAA,QACF;AAAA;AAAA;AAAA,EAEJ;AAEJ;","names":[]}
@@ -1,8 +1,8 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
- import { Dialog } from '@radix-ui/themes';
3
2
  import { ReactNode } from 'react';
3
+ import { RootProps } from '@radix-ui/themes/components/dialog';
4
4
 
5
- interface SetPasswordDialogProps extends Dialog.RootProps {
5
+ interface SetPasswordDialogProps extends RootProps {
6
6
  children?: ReactNode;
7
7
  }
8
8
  declare function SetPasswordDialog({ children, ...props }: SetPasswordDialogProps): react_jsx_runtime.JSX.Element;
@@ -1,14 +1,8 @@
1
1
  "use client";
2
2
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
3
- import { Callout, Dialog, Flex, Text, VisuallyHidden } from "@radix-ui/themes";
3
+ import { Callout, Flex, Text, VisuallyHidden } from "@radix-ui/themes";
4
4
  import * as React from "react";
5
- import {
6
- DialogContent,
7
- Label,
8
- PasswordField,
9
- PrimaryButton,
10
- SecondaryButton
11
- } from "./elements.js";
5
+ import { Dialog, Label, PasswordField, Button } from "./elements.js";
12
6
  import * as Form from "@radix-ui/react-form";
13
7
  import { useCreatePassword } from "../api/endpoint.js";
14
8
  import { useSecuritySettings } from "./use-security-settings.js";
@@ -25,7 +19,7 @@ function SetPasswordDialog({
25
19
  }, []);
26
20
  return /* @__PURE__ */ jsxs(Dialog.Root, { ...props, open, onOpenChange: setOpen, children: [
27
21
  /* @__PURE__ */ jsx(Dialog.Trigger, { children }),
28
- /* @__PURE__ */ jsx(DialogContent, { maxWidth: "480px", children: /* @__PURE__ */ jsx(ElevatedAccess, { children: /* @__PURE__ */ jsx(Content, { onClose: handleClose }) }) })
22
+ /* @__PURE__ */ jsx(Dialog.Content, { maxWidth: "480px", children: /* @__PURE__ */ jsx(ElevatedAccess, { children: /* @__PURE__ */ jsx(Content, { onClose: handleClose }) }) })
29
23
  ] });
30
24
  }
31
25
  function Content({ onClose }) {
@@ -99,8 +93,9 @@ function Content({ onClose }) {
99
93
  ] }),
100
94
  /* @__PURE__ */ jsxs(Flex, { mt: "5", gap: "3", justify: "end", children: [
101
95
  /* @__PURE__ */ jsx(Dialog.Close, { children: /* @__PURE__ */ jsx(
102
- SecondaryButton,
96
+ Button,
103
97
  {
98
+ variant: "secondary",
104
99
  disabled: setPassword.isPending || setPassword.isSuccess,
105
100
  children: "Cancel"
106
101
  }
@@ -108,11 +103,12 @@ function Content({ onClose }) {
108
103
  /* @__PURE__ */ jsx(
109
104
  SaveButton,
110
105
  {
111
- asChild: true,
112
106
  loading: setPassword.isPending,
113
107
  done: setPassword.isSuccess,
114
108
  onDone: onClose,
115
- children: /* @__PURE__ */ jsx(PrimaryButton, { type: "submit", disabled: disableSubmit, children: "Set password" })
109
+ type: "submit",
110
+ disabled: disableSubmit || void 0,
111
+ children: "Set password"
116
112
  }
117
113
  )
118
114
  ] }),
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/lib/set-password-dialog.tsx"],"sourcesContent":["\"use client\";\n\nimport { Callout, Dialog, Flex, Text, VisuallyHidden } from \"@radix-ui/themes\";\nimport * as React from \"react\";\nimport { type ReactNode } from \"react\";\nimport {\n DialogContent,\n Label,\n PasswordField,\n PrimaryButton,\n SecondaryButton,\n} from \"./elements.js\";\nimport * as Form from \"@radix-ui/react-form\";\nimport { useCreatePassword } from \"../api/endpoint.js\";\nimport { useSecuritySettings } from \"./use-security-settings.js\";\nimport { ElevatedAccess } from \"./elevated-access.js\";\nimport { SaveButton } from \"./save-button.js\";\nimport { useDialogClose } from \"./use-dialog-close.js\";\n\ninterface SetPasswordDialogProps extends Dialog.RootProps {\n children?: ReactNode;\n}\n\nexport function SetPasswordDialog({\n children,\n ...props\n}: SetPasswordDialogProps) {\n const [open, setOpen] = React.useState(false);\n\n const handleClose = React.useCallback(() => {\n setOpen(false);\n }, []);\n\n return (\n <Dialog.Root {...props} open={open} onOpenChange={setOpen}>\n <Dialog.Trigger>{children}</Dialog.Trigger>\n\n <DialogContent maxWidth=\"480px\">\n <ElevatedAccess>\n <Content onClose={handleClose} />\n </ElevatedAccess>\n </DialogContent>\n </Dialog.Root>\n );\n}\n\ninterface ContentProps {\n onClose: () => void;\n}\n\nfunction Content({ onClose }: ContentProps) {\n const setPassword = useCreatePassword();\n const securitySettings = useSecuritySettings();\n const [disableSubmit, setDisableSubmit] = React.useState(true);\n\n const handleSubmit = async (event: React.FormEvent<HTMLFormElement>) => {\n event.preventDefault();\n\n const formData = new FormData(event.currentTarget);\n const password = formData.get(\"password\")?.toString();\n\n if (!password) {\n return;\n }\n\n setPassword.mutate({ data: { password } });\n };\n\n useDialogClose(setPassword.isSuccess, () => {\n securitySettings.update(\"Password\", true);\n });\n\n return (\n <>\n <Dialog.Title mb=\"5\">Set New Password</Dialog.Title>\n <VisuallyHidden>\n <Dialog.Description>\n Set a new password for your account\n </Dialog.Description>\n </VisuallyHidden>\n\n {setPassword.error ? (\n <Callout.Root color=\"red\" my=\"-2\">\n <Callout.Text>\n {getMutationErrorMessage(setPassword.error)}\n </Callout.Text>\n </Callout.Root>\n ) : null}\n\n <Form.Root\n onSubmit={handleSubmit}\n onChange={(event) => {\n const formData = new FormData(event.currentTarget);\n const password = formData.get(\"password\")?.toString();\n const confirmPassword = formData.get(\"confirmPassword\")?.toString();\n setDisableSubmit(password === \"\" || confirmPassword === \"\");\n }}\n >\n <Flex mt=\"5\" direction=\"column\" gap=\"4\">\n <Form.Field name=\"password\" asChild>\n <Flex direction=\"column\" gap=\"2\">\n <Form.Label asChild>\n <Label>Enter a new password</Label>\n </Form.Label>\n <Form.Control asChild>\n <PasswordField\n autoFocus\n required\n autoComplete=\"new-password\"\n placeholder=\"New password\"\n disabled={setPassword.isPending || setPassword.isSuccess}\n />\n </Form.Control>\n <Form.Message match=\"valueMissing\" asChild>\n <Text size=\"2\" color=\"red\">\n Please enter a new password\n </Text>\n </Form.Message>\n <Form.Message match={(value) => value.length < 8} asChild>\n <Text size=\"2\" color=\"red\">\n Password must be at least 8 characters\n </Text>\n </Form.Message>\n </Flex>\n </Form.Field>\n\n <Form.Field name=\"confirmPassword\" asChild>\n <Flex direction=\"column\" gap=\"2\">\n <Form.Label asChild>\n <Label>Confirm your new password</Label>\n </Form.Label>\n <Form.Control asChild>\n <PasswordField\n required\n autoComplete=\"new-password\"\n placeholder=\"Confirm new password\"\n disabled={setPassword.isPending || setPassword.isSuccess}\n />\n </Form.Control>\n <Form.Message match=\"valueMissing\" asChild>\n <Text size=\"2\" color=\"red\">\n Please confirm your new password\n </Text>\n </Form.Message>\n <Form.Message\n match={(value, formData) => value !== formData.get(\"password\")}\n asChild\n >\n <Text size=\"2\" color=\"red\">\n The passwords you entered don’t match.\n </Text>\n </Form.Message>\n </Flex>\n </Form.Field>\n </Flex>\n\n <Flex mt=\"5\" gap=\"3\" justify=\"end\">\n <Dialog.Close>\n <SecondaryButton\n disabled={setPassword.isPending || setPassword.isSuccess}\n >\n Cancel\n </SecondaryButton>\n </Dialog.Close>\n\n <SaveButton\n asChild\n loading={setPassword.isPending}\n done={setPassword.isSuccess}\n onDone={onClose}\n >\n <PrimaryButton type=\"submit\" disabled={disableSubmit}>\n Set password\n </PrimaryButton>\n </SaveButton>\n </Flex>\n\n {/* mirror errors in a live region */}\n <VisuallyHidden asChild>\n <section aria-live=\"polite\">\n {getMutationErrorMessage(setPassword.error)}\n </section>\n </VisuallyHidden>\n </Form.Root>\n </>\n );\n}\n\nfunction getMutationErrorMessage(error: unknown) {\n if (error instanceof Error) {\n return error.message;\n }\n\n if (\n typeof error === \"object\" &&\n error !== null &&\n \"message\" in error &&\n typeof error.message === \"string\"\n ) {\n return error.message;\n }\n\n return \"Something went wrong. Please try again.\";\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../../src/lib/set-password-dialog.tsx"],"sourcesContent":["\"use client\";\n\nimport { Callout, Flex, Text, VisuallyHidden } from \"@radix-ui/themes\";\nimport * as React from \"react\";\nimport { type ReactNode } from \"react\";\nimport { Dialog, Label, PasswordField, Button } from \"./elements.js\";\nimport * as Form from \"@radix-ui/react-form\";\nimport { useCreatePassword } from \"../api/endpoint.js\";\nimport { useSecuritySettings } from \"./use-security-settings.js\";\nimport { ElevatedAccess } from \"./elevated-access.js\";\nimport { SaveButton } from \"./save-button.js\";\nimport { useDialogClose } from \"./use-dialog-close.js\";\n\ninterface SetPasswordDialogProps extends Dialog.RootProps {\n children?: ReactNode;\n}\n\nexport function SetPasswordDialog({\n children,\n ...props\n}: SetPasswordDialogProps) {\n const [open, setOpen] = React.useState(false);\n\n const handleClose = React.useCallback(() => {\n setOpen(false);\n }, []);\n\n return (\n <Dialog.Root {...props} open={open} onOpenChange={setOpen}>\n <Dialog.Trigger>{children}</Dialog.Trigger>\n\n <Dialog.Content maxWidth=\"480px\">\n <ElevatedAccess>\n <Content onClose={handleClose} />\n </ElevatedAccess>\n </Dialog.Content>\n </Dialog.Root>\n );\n}\n\ninterface ContentProps {\n onClose: () => void;\n}\n\nfunction Content({ onClose }: ContentProps) {\n const setPassword = useCreatePassword();\n const securitySettings = useSecuritySettings();\n const [disableSubmit, setDisableSubmit] = React.useState(true);\n\n const handleSubmit = async (event: React.FormEvent<HTMLFormElement>) => {\n event.preventDefault();\n\n const formData = new FormData(event.currentTarget);\n const password = formData.get(\"password\")?.toString();\n\n if (!password) {\n return;\n }\n\n setPassword.mutate({ data: { password } });\n };\n\n useDialogClose(setPassword.isSuccess, () => {\n securitySettings.update(\"Password\", true);\n });\n\n return (\n <>\n <Dialog.Title mb=\"5\">Set New Password</Dialog.Title>\n <VisuallyHidden>\n <Dialog.Description>\n Set a new password for your account\n </Dialog.Description>\n </VisuallyHidden>\n\n {setPassword.error ? (\n <Callout.Root color=\"red\" my=\"-2\">\n <Callout.Text>\n {getMutationErrorMessage(setPassword.error)}\n </Callout.Text>\n </Callout.Root>\n ) : null}\n\n <Form.Root\n onSubmit={handleSubmit}\n onChange={(event) => {\n const formData = new FormData(event.currentTarget);\n const password = formData.get(\"password\")?.toString();\n const confirmPassword = formData.get(\"confirmPassword\")?.toString();\n setDisableSubmit(password === \"\" || confirmPassword === \"\");\n }}\n >\n <Flex mt=\"5\" direction=\"column\" gap=\"4\">\n <Form.Field name=\"password\" asChild>\n <Flex direction=\"column\" gap=\"2\">\n <Form.Label asChild>\n <Label>Enter a new password</Label>\n </Form.Label>\n <Form.Control asChild>\n <PasswordField\n autoFocus\n required\n autoComplete=\"new-password\"\n placeholder=\"New password\"\n disabled={setPassword.isPending || setPassword.isSuccess}\n />\n </Form.Control>\n <Form.Message match=\"valueMissing\" asChild>\n <Text size=\"2\" color=\"red\">\n Please enter a new password\n </Text>\n </Form.Message>\n <Form.Message match={(value) => value.length < 8} asChild>\n <Text size=\"2\" color=\"red\">\n Password must be at least 8 characters\n </Text>\n </Form.Message>\n </Flex>\n </Form.Field>\n\n <Form.Field name=\"confirmPassword\" asChild>\n <Flex direction=\"column\" gap=\"2\">\n <Form.Label asChild>\n <Label>Confirm your new password</Label>\n </Form.Label>\n <Form.Control asChild>\n <PasswordField\n required\n autoComplete=\"new-password\"\n placeholder=\"Confirm new password\"\n disabled={setPassword.isPending || setPassword.isSuccess}\n />\n </Form.Control>\n <Form.Message match=\"valueMissing\" asChild>\n <Text size=\"2\" color=\"red\">\n Please confirm your new password\n </Text>\n </Form.Message>\n <Form.Message\n match={(value, formData) => value !== formData.get(\"password\")}\n asChild\n >\n <Text size=\"2\" color=\"red\">\n The passwords you entered don’t match.\n </Text>\n </Form.Message>\n </Flex>\n </Form.Field>\n </Flex>\n\n <Flex mt=\"5\" gap=\"3\" justify=\"end\">\n <Dialog.Close>\n <Button\n variant=\"secondary\"\n disabled={setPassword.isPending || setPassword.isSuccess}\n >\n Cancel\n </Button>\n </Dialog.Close>\n\n <SaveButton\n loading={setPassword.isPending}\n done={setPassword.isSuccess}\n onDone={onClose}\n type=\"submit\"\n disabled={disableSubmit || undefined}\n >\n Set password\n </SaveButton>\n </Flex>\n\n {/* mirror errors in a live region */}\n <VisuallyHidden asChild>\n <section aria-live=\"polite\">\n {getMutationErrorMessage(setPassword.error)}\n </section>\n </VisuallyHidden>\n </Form.Root>\n </>\n );\n}\n\nfunction getMutationErrorMessage(error: unknown) {\n if (error instanceof Error) {\n return error.message;\n }\n\n if (\n typeof error === \"object\" &&\n error !== null &&\n \"message\" in error &&\n typeof error.message === \"string\"\n ) {\n return error.message;\n }\n\n return \"Something went wrong. Please try again.\";\n}\n"],"mappings":"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","names":[]}
@@ -1,15 +1,10 @@
1
1
  "use client";
2
2
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
3
- import { DropdownMenu } from "@radix-ui/themes";
4
3
  import * as React from "react";
5
4
  import { useRolesAndConfig } from "../api/endpoint.js";
6
5
  import { DeleteUserDialog } from "./delete-user-dialog.js";
7
6
  import { EditUserRoleDialog } from "./edit-user-role-dialog.js";
8
- import {
9
- DestructiveMenuItem,
10
- DropdownMenuContent,
11
- PrimaryMenuItem
12
- } from "./elements.js";
7
+ import { DropdownMenu } from "./elements.js";
13
8
  import { ResendInviteDialog } from "./resend-invite-dialog.js";
14
9
  import { RevokeInviteDialog } from "./revoke-invite-dialog.js";
15
10
  const UserActionsDropdown = ({
@@ -34,7 +29,7 @@ const UserActionsDropdown = ({
34
29
  if (actions2.has("edit-role")) {
35
30
  items2.push(
36
31
  /* @__PURE__ */ jsx(
37
- PrimaryMenuItem,
32
+ DropdownMenu.Item,
38
33
  {
39
34
  onSelect: () => setOpenDialog("edit-role"),
40
35
  disabled: rolesAndConfigQuery.isLoading || rolesAndConfigQuery.isSuccess && roles.length <= 1,
@@ -48,7 +43,7 @@ const UserActionsDropdown = ({
48
43
  if (actions2.has("resend-invite")) {
49
44
  items2.push(
50
45
  /* @__PURE__ */ jsx(
51
- PrimaryMenuItem,
46
+ DropdownMenu.Item,
52
47
  {
53
48
  onSelect: () => setOpenDialog("resend-invite"),
54
49
  children: "Resend invitation"
@@ -60,8 +55,9 @@ const UserActionsDropdown = ({
60
55
  if (actions2.has("revoke-invite")) {
61
56
  items2.push(
62
57
  /* @__PURE__ */ jsx(
63
- DestructiveMenuItem,
58
+ DropdownMenu.Item,
64
59
  {
60
+ variant: "destructive",
65
61
  onSelect: () => setOpenDialog("revoke-invite"),
66
62
  children: "Revoke invitation"
67
63
  },
@@ -72,8 +68,9 @@ const UserActionsDropdown = ({
72
68
  if (actions2.has("revoke-membership")) {
73
69
  items2.push(
74
70
  /* @__PURE__ */ jsx(
75
- DestructiveMenuItem,
71
+ DropdownMenu.Item,
76
72
  {
73
+ variant: "destructive",
77
74
  onSelect: () => setOpenDialog("revoke-membership"),
78
75
  children: "Remove user"
79
76
  },
@@ -92,7 +89,7 @@ const UserActionsDropdown = ({
92
89
  return /* @__PURE__ */ jsxs(Fragment, { children: [
93
90
  /* @__PURE__ */ jsxs(DropdownMenu.Root, { children: [
94
91
  /* @__PURE__ */ jsx(DropdownMenu.Trigger, { children }),
95
- /* @__PURE__ */ jsx(DropdownMenuContent, { size: "2", align: "end", children: items })
92
+ /* @__PURE__ */ jsx(DropdownMenu.Content, { size: "2", align: "end", children: items })
96
93
  ] }),
97
94
  actions.has("edit-role") && /* @__PURE__ */ jsx(
98
95
  EditUserRoleDialog,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/lib/user-actions-dropdown.tsx"],"sourcesContent":["\"use client\";\n\nimport { DropdownMenu } from \"@radix-ui/themes\";\nimport * as React from \"react\";\nimport { Member, useRolesAndConfig } from \"../api/endpoint.js\";\nimport { DeleteUserDialog } from \"./delete-user-dialog.js\";\nimport { EditUserRoleDialog } from \"./edit-user-role-dialog.js\";\nimport {\n DestructiveMenuItem,\n DropdownMenuContent,\n PrimaryMenuItem,\n} from \"./elements.js\";\nimport { ResendInviteDialog } from \"./resend-invite-dialog.js\";\nimport { RevokeInviteDialog } from \"./revoke-invite-dialog.js\";\n\ninterface UserActionsDropdownProps {\n user: Member;\n children: React.ReactNode;\n}\n\ntype UserActionDialog =\n | \"revoke-membership\"\n | \"revoke-invite\"\n | \"resend-invite\"\n | \"edit-role\";\n\nexport const UserActionsDropdown = ({\n user,\n children,\n}: UserActionsDropdownProps) => {\n const rolesAndConfigQuery = useRolesAndConfig({\n query: {\n initialData: { roles: [], multipleRolesEnabled: false },\n },\n });\n const { roles, multipleRolesEnabled: isMultipleRolesEnabled } =\n rolesAndConfigQuery.data;\n const [openDialog, setOpenDialog] = React.useState<UserActionDialog | null>(\n null,\n );\n\n /**\n * Assigns a key for each dialog based on its open state to ensure its\n * internal state is cleared when it is closed.\n */\n function getDialogKey(dialog: UserActionDialog) {\n return `${dialog}-${openDialog === dialog}-${user.id}`;\n }\n\n const { actions, items } = React.useMemo(() => {\n const actions = new Set(user.actions);\n const items: React.ReactElement[] = [];\n if (actions.has(\"edit-role\")) {\n items.push(\n <PrimaryMenuItem\n key=\"edit-role\"\n onSelect={() => setOpenDialog(\"edit-role\")}\n disabled={\n rolesAndConfigQuery.isLoading ||\n (rolesAndConfigQuery.isSuccess && roles.length <= 1)\n }\n title={\n rolesAndConfigQuery.isSuccess && roles.length <= 1\n ? \"You cannot update the role for this user as there is only one role available.\"\n : undefined\n }\n >\n {`Edit role${isMultipleRolesEnabled ? \"s\" : \"\"}`}\n </PrimaryMenuItem>,\n );\n }\n if (actions.has(\"resend-invite\")) {\n items.push(\n <PrimaryMenuItem\n key=\"resend-invite\"\n onSelect={() => setOpenDialog(\"resend-invite\")}\n >\n Resend invitation\n </PrimaryMenuItem>,\n );\n }\n if (actions.has(\"revoke-invite\")) {\n items.push(\n <DestructiveMenuItem\n key=\"revoke-invite\"\n onSelect={() => setOpenDialog(\"revoke-invite\")}\n >\n Revoke invitation\n </DestructiveMenuItem>,\n );\n }\n if (actions.has(\"revoke-membership\")) {\n items.push(\n <DestructiveMenuItem\n key=\"revoke-membership\"\n onSelect={() => setOpenDialog(\"revoke-membership\")}\n >\n Remove user\n </DestructiveMenuItem>,\n );\n }\n return {\n actions,\n items,\n };\n }, [rolesAndConfigQuery, user.actions, isMultipleRolesEnabled, roles]);\n\n if (user.isLoggedInUser || items.length === 0) {\n return null;\n }\n\n return (\n <>\n <DropdownMenu.Root>\n <DropdownMenu.Trigger>{children}</DropdownMenu.Trigger>\n <DropdownMenuContent size=\"2\" align=\"end\">\n {items}\n </DropdownMenuContent>\n </DropdownMenu.Root>\n\n {actions.has(\"edit-role\") && (\n <EditUserRoleDialog\n key={getDialogKey(\"edit-role\")}\n user={user}\n open={openDialog === \"edit-role\"}\n onOpenChange={(open) => !open && setOpenDialog(null)}\n />\n )}\n\n {actions.has(\"revoke-membership\") && (\n <DeleteUserDialog\n key={getDialogKey(\"revoke-membership\")}\n user={user}\n open={openDialog === \"revoke-membership\"}\n onOpenChange={(open) => !open && setOpenDialog(null)}\n />\n )}\n\n {actions.has(\"revoke-invite\") && (\n <RevokeInviteDialog\n key={getDialogKey(\"revoke-invite\")}\n user={user}\n open={openDialog === \"revoke-invite\"}\n onOpenChange={(open) => !open && setOpenDialog(null)}\n />\n )}\n\n {actions.has(\"resend-invite\") && (\n <ResendInviteDialog\n key={getDialogKey(\"resend-invite\")}\n user={user}\n open={openDialog === \"resend-invite\"}\n onOpenChange={(open) => !open && setOpenDialog(null)}\n />\n )}\n </>\n );\n};\n"],"mappings":"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","names":["actions","items"]}
1
+ {"version":3,"sources":["../../../src/lib/user-actions-dropdown.tsx"],"sourcesContent":["\"use client\";\n\nimport * as React from \"react\";\nimport { Member, useRolesAndConfig } from \"../api/endpoint.js\";\nimport { DeleteUserDialog } from \"./delete-user-dialog.js\";\nimport { EditUserRoleDialog } from \"./edit-user-role-dialog.js\";\nimport { DropdownMenu } from \"./elements.js\";\nimport { ResendInviteDialog } from \"./resend-invite-dialog.js\";\nimport { RevokeInviteDialog } from \"./revoke-invite-dialog.js\";\n\ninterface UserActionsDropdownProps {\n user: Member;\n children: React.ReactNode;\n}\n\ntype UserActionDialog =\n | \"revoke-membership\"\n | \"revoke-invite\"\n | \"resend-invite\"\n | \"edit-role\";\n\nexport const UserActionsDropdown = ({\n user,\n children,\n}: UserActionsDropdownProps) => {\n const rolesAndConfigQuery = useRolesAndConfig({\n query: {\n initialData: { roles: [], multipleRolesEnabled: false },\n },\n });\n const { roles, multipleRolesEnabled: isMultipleRolesEnabled } =\n rolesAndConfigQuery.data;\n const [openDialog, setOpenDialog] = React.useState<UserActionDialog | null>(\n null,\n );\n\n /**\n * Assigns a key for each dialog based on its open state to ensure its\n * internal state is cleared when it is closed.\n */\n function getDialogKey(dialog: UserActionDialog) {\n return `${dialog}-${openDialog === dialog}-${user.id}`;\n }\n\n const { actions, items } = React.useMemo(() => {\n const actions = new Set(user.actions);\n const items: React.ReactElement[] = [];\n if (actions.has(\"edit-role\")) {\n items.push(\n <DropdownMenu.Item\n key=\"edit-role\"\n onSelect={() => setOpenDialog(\"edit-role\")}\n disabled={\n rolesAndConfigQuery.isLoading ||\n (rolesAndConfigQuery.isSuccess && roles.length <= 1)\n }\n title={\n rolesAndConfigQuery.isSuccess && roles.length <= 1\n ? \"You cannot update the role for this user as there is only one role available.\"\n : undefined\n }\n >\n {`Edit role${isMultipleRolesEnabled ? \"s\" : \"\"}`}\n </DropdownMenu.Item>,\n );\n }\n if (actions.has(\"resend-invite\")) {\n items.push(\n <DropdownMenu.Item\n key=\"resend-invite\"\n onSelect={() => setOpenDialog(\"resend-invite\")}\n >\n Resend invitation\n </DropdownMenu.Item>,\n );\n }\n if (actions.has(\"revoke-invite\")) {\n items.push(\n <DropdownMenu.Item\n variant=\"destructive\"\n key=\"revoke-invite\"\n onSelect={() => setOpenDialog(\"revoke-invite\")}\n >\n Revoke invitation\n </DropdownMenu.Item>,\n );\n }\n if (actions.has(\"revoke-membership\")) {\n items.push(\n <DropdownMenu.Item\n variant=\"destructive\"\n key=\"revoke-membership\"\n onSelect={() => setOpenDialog(\"revoke-membership\")}\n >\n Remove user\n </DropdownMenu.Item>,\n );\n }\n return {\n actions,\n items,\n };\n }, [rolesAndConfigQuery, user.actions, isMultipleRolesEnabled, roles]);\n\n if (user.isLoggedInUser || items.length === 0) {\n return null;\n }\n\n return (\n <>\n <DropdownMenu.Root>\n <DropdownMenu.Trigger>{children}</DropdownMenu.Trigger>\n <DropdownMenu.Content size=\"2\" align=\"end\">\n {items}\n </DropdownMenu.Content>\n </DropdownMenu.Root>\n\n {actions.has(\"edit-role\") && (\n <EditUserRoleDialog\n key={getDialogKey(\"edit-role\")}\n user={user}\n open={openDialog === \"edit-role\"}\n onOpenChange={(open) => !open && setOpenDialog(null)}\n />\n )}\n\n {actions.has(\"revoke-membership\") && (\n <DeleteUserDialog\n key={getDialogKey(\"revoke-membership\")}\n user={user}\n open={openDialog === \"revoke-membership\"}\n onOpenChange={(open) => !open && setOpenDialog(null)}\n />\n )}\n\n {actions.has(\"revoke-invite\") && (\n <RevokeInviteDialog\n key={getDialogKey(\"revoke-invite\")}\n user={user}\n open={openDialog === \"revoke-invite\"}\n onOpenChange={(open) => !open && setOpenDialog(null)}\n />\n )}\n\n {actions.has(\"resend-invite\") && (\n <ResendInviteDialog\n key={getDialogKey(\"resend-invite\")}\n user={user}\n open={openDialog === \"resend-invite\"}\n onOpenChange={(open) => !open && setOpenDialog(null)}\n />\n )}\n </>\n );\n};\n"],"mappings":"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","names":["actions","items"]}
@@ -3,6 +3,17 @@ import { Me } from '../api/endpoint.js';
3
3
  import { WidgetRootDomProps } from './utils.js';
4
4
  import '@tanstack/react-query';
5
5
  import '../api/widgets-api-client.js';
6
+ import './elements.js';
7
+ import '@radix-ui/themes';
8
+ import '@radix-ui/themes/props';
9
+ import '../dialog-C15qCLN3.js';
10
+ import '@radix-ui/themes/components/dialog';
11
+ import '../alert-dialog-BlG3_awx.js';
12
+ import '@radix-ui/themes/components/alert-dialog';
13
+ import '../dropdown-menu-BQ5LtvdR.js';
14
+ import '@radix-ui/themes/components/dropdown-menu';
15
+ import '../select-KR89Qnvm.js';
16
+ import '@radix-ui/themes/components/select';
6
17
 
7
18
  interface UserProfileProps extends WidgetRootDomProps {
8
19
  userData: Me;
@@ -10,7 +10,7 @@ import {
10
10
  Strong,
11
11
  Text
12
12
  } from "@radix-ui/themes";
13
- import { Avatar, SecondaryButton, Skeleton } from "./elements.js";
13
+ import { Avatar, Button, Skeleton } from "./elements.js";
14
14
  import { EditUserProfileDialog } from "./edit-user-profile-dialog.js";
15
15
  import {
16
16
  getBestName,
@@ -56,7 +56,7 @@ const UserProfile = ({
56
56
  children: "Not set"
57
57
  }
58
58
  ) }),
59
- /* @__PURE__ */ jsx(EditUserProfileDialog, { user, children: /* @__PURE__ */ jsx(SecondaryButton, { children: "Edit" }) })
59
+ /* @__PURE__ */ jsx(EditUserProfileDialog, { user, children: /* @__PURE__ */ jsx(Button, { variant: "secondary", children: "Edit" }) })
60
60
  ]
61
61
  }
62
62
  ) })
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/lib/user-profile.tsx"],"sourcesContent":["\"use client\";\n\nimport * as React from \"react\";\nimport {\n Box,\n Card,\n DataList,\n Flex,\n Inset,\n Separator,\n Strong,\n Text,\n} from \"@radix-ui/themes\";\nimport { Avatar, SecondaryButton, Skeleton } from \"./elements.js\";\nimport { Me, OAuthProfile, MeOauthProfiles } from \"../api/endpoint.js\";\nimport { EditUserProfileDialog } from \"./edit-user-profile-dialog.js\";\nimport {\n getBestName,\n getDomProps,\n type WidgetRootState,\n type WidgetRootDomProps,\n} from \"./utils.js\";\nimport { OAuthIcon, getOAuthName, type OAuthAccount } from \"./oauth-icons.js\";\nimport { GenericError } from \"./generic-error.js\";\n\ninterface UserProfileProps extends WidgetRootDomProps {\n userData: Me;\n}\n\nconst UserProfile: React.FC<UserProfileProps> = ({\n userData: user,\n ...domProps\n}) => {\n const oauthAccounts = user.oauthProfiles\n ? (Object.entries(user.oauthProfiles) as [\n keyof Exclude<MeOauthProfiles, null>,\n OAuthProfile,\n ][])\n : [];\n return (\n <Card size=\"2\" {...getWidgetRootDomProps(\"resolved\", domProps)}>\n <DataList.Root>\n {user.profilePictureUrl && (\n <>\n <DataList.Item align=\"center\">\n <DataList.Label minWidth=\"220px\" highContrast>\n <Strong>Profile picture</Strong>\n </DataList.Label>\n <DataList.Value>\n <Avatar\n size=\"2\"\n fallback={<FallbackUserIcon />}\n src={user.profilePictureUrl}\n />\n </DataList.Value>\n </DataList.Item>\n\n <ListSeparator />\n </>\n )}\n\n <DataList.Item align=\"center\">\n <DataList.Label highContrast>\n <Strong>Full name</Strong>\n </DataList.Label>\n <DataList.Value>\n <Flex\n align=\"center\"\n justify=\"between\"\n width=\"100%\"\n minHeight=\"var(--space-6)\"\n >\n <Text size=\"2\">\n {getBestName(user) || (\n <Text\n color=\"gray\"\n style={{ color: \"var(--gray-10)\", cursor: \"default\" }}\n >\n Not set\n </Text>\n )}\n </Text>\n\n <EditUserProfileDialog user={user}>\n <SecondaryButton>Edit</SecondaryButton>\n </EditUserProfileDialog>\n </Flex>\n </DataList.Value>\n </DataList.Item>\n\n <ListSeparator />\n\n <DataList.Item align=\"center\">\n <DataList.Label highContrast>\n <Strong>Email address</Strong>\n </DataList.Label>\n <DataList.Value>\n <Flex align=\"center\" minHeight=\"var(--space-6)\">\n <Text size=\"2\">{user.email}</Text>\n </Flex>\n </DataList.Value>\n </DataList.Item>\n\n {oauthAccounts.length > 0 && (\n <>\n <ListSeparator />\n\n <DataList.Item>\n <DataList.Label highContrast>\n <Strong>Connected accounts</Strong>\n </DataList.Label>\n <DataList.Value>\n <Flex direction=\"column\" gap=\"2\">\n {oauthAccounts.map(([account, data]) => (\n <OAuthAccount\n key={account}\n account={account}\n email={data?.email}\n />\n ))}\n </Flex>\n </DataList.Value>\n </DataList.Item>\n </>\n )}\n </DataList.Root>\n </Card>\n );\n};\n\ninterface UserProfileLoadingProps extends WidgetRootDomProps {}\n\nconst UserProfileLoading: React.FC<UserProfileLoadingProps> = (props) => {\n return (\n <Card size=\"2\" {...getWidgetRootDomProps(\"loading\", props)}>\n <DataList.Root>\n <DataList.Item align=\"center\">\n <DataList.Label minWidth=\"220px\" highContrast>\n <Strong>\n <Skeleton>Full name</Skeleton>\n </Strong>\n </DataList.Label>\n <DataList.Value>\n <Flex\n align=\"center\"\n justify=\"between\"\n width=\"100%\"\n minHeight=\"var(--space-6)\"\n >\n <Text size=\"2\">\n <Skeleton>Full name</Skeleton>\n </Text>\n </Flex>\n </DataList.Value>\n </DataList.Item>\n\n <ListSeparator />\n\n <DataList.Item align=\"center\">\n <DataList.Label highContrast>\n <Strong>\n <Skeleton>Email address</Skeleton>\n </Strong>\n </DataList.Label>\n <DataList.Value>\n <Flex align=\"center\" minHeight=\"var(--space-6)\">\n <Text size=\"2\">\n <Skeleton>Email address</Skeleton>\n </Text>\n </Flex>\n </DataList.Value>\n </DataList.Item>\n </DataList.Root>\n </Card>\n );\n};\n\ninterface UserProfileErrorProps extends WidgetRootDomProps {\n error: unknown;\n}\n\nconst UserProfileError: React.FC<UserProfileErrorProps> = ({\n error,\n ...domProps\n}) => {\n return (\n <Card size=\"2\" {...getWidgetRootDomProps(\"error\", domProps)}>\n <GenericError error={error} />\n </Card>\n );\n};\n\nconst ListSeparator = () => (\n <Box asChild gridColumn=\"span 2\">\n <Inset side=\"x\">\n <Separator size=\"4\" />\n </Inset>\n </Box>\n);\n\nconst OAuthAccount = ({\n account,\n email,\n}: {\n account: OAuthAccount;\n email?: string | null;\n}) => {\n const name = getOAuthName(account);\n return (\n <Flex align=\"center\" gap=\"1\">\n <OAuthIcon account={account} />\n <Text size=\"2\" ml=\"1\">\n {name}\n </Text>\n {email && (\n <Box display={{ initial: \"none\", sm: \"contents\" }}>\n <Text size=\"2\" color=\"gray\">\n ∙\n </Text>\n <Text size=\"2\" color=\"gray\">\n {email}\n </Text>\n </Box>\n )}\n </Flex>\n );\n};\n\nconst FallbackUserIcon = () => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"20\"\n height=\"20\"\n fill=\"currentColor\"\n viewBox=\"0 0 256 256\"\n >\n <title>User icon</title>\n <path d=\"M229.19,213c-15.81-27.32-40.63-46.49-69.47-54.62a70,70,0,1,0-63.44,0C67.44,166.5,42.62,185.67,26.81,213a6,6,0,1,0,10.38,6C56.4,185.81,90.34,166,128,166s71.6,19.81,90.81,53a6,6,0,1,0,10.38-6ZM70,96a58,58,0,1,1,58,58A58.07,58.07,0,0,1,70,96Z\" />\n </svg>\n);\n\nfunction getWidgetRootDomProps(\n state: WidgetRootState,\n domProps: WidgetRootDomProps,\n) {\n return getDomProps({\n ...domProps,\n isWidgetRoot: true,\n widgetId: \"user-profile\",\n widgetState: state,\n });\n}\n\nexport type {\n UserProfileProps,\n UserProfileLoadingProps,\n UserProfileErrorProps,\n};\nexport { UserProfile, UserProfileLoading, UserProfileError };\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../../src/lib/user-profile.tsx"],"sourcesContent":["\"use client\";\n\nimport * as React from \"react\";\nimport {\n Box,\n Card,\n DataList,\n Flex,\n Inset,\n Separator,\n Strong,\n Text,\n} from \"@radix-ui/themes\";\nimport { Avatar, Button, Skeleton } from \"./elements.js\";\nimport { Me, OAuthProfile, MeOauthProfiles } from \"../api/endpoint.js\";\nimport { EditUserProfileDialog } from \"./edit-user-profile-dialog.js\";\nimport {\n getBestName,\n getDomProps,\n type WidgetRootState,\n type WidgetRootDomProps,\n} from \"./utils.js\";\nimport { OAuthIcon, getOAuthName, type OAuthAccount } from \"./oauth-icons.js\";\nimport { GenericError } from \"./generic-error.js\";\n\ninterface UserProfileProps extends WidgetRootDomProps {\n userData: Me;\n}\n\nconst UserProfile: React.FC<UserProfileProps> = ({\n userData: user,\n ...domProps\n}) => {\n const oauthAccounts = user.oauthProfiles\n ? (Object.entries(user.oauthProfiles) as [\n keyof Exclude<MeOauthProfiles, null>,\n OAuthProfile,\n ][])\n : [];\n return (\n <Card size=\"2\" {...getWidgetRootDomProps(\"resolved\", domProps)}>\n <DataList.Root>\n {user.profilePictureUrl && (\n <>\n <DataList.Item align=\"center\">\n <DataList.Label minWidth=\"220px\" highContrast>\n <Strong>Profile picture</Strong>\n </DataList.Label>\n <DataList.Value>\n <Avatar\n size=\"2\"\n fallback={<FallbackUserIcon />}\n src={user.profilePictureUrl}\n />\n </DataList.Value>\n </DataList.Item>\n\n <ListSeparator />\n </>\n )}\n\n <DataList.Item align=\"center\">\n <DataList.Label highContrast>\n <Strong>Full name</Strong>\n </DataList.Label>\n <DataList.Value>\n <Flex\n align=\"center\"\n justify=\"between\"\n width=\"100%\"\n minHeight=\"var(--space-6)\"\n >\n <Text size=\"2\">\n {getBestName(user) || (\n <Text\n color=\"gray\"\n style={{ color: \"var(--gray-10)\", cursor: \"default\" }}\n >\n Not set\n </Text>\n )}\n </Text>\n\n <EditUserProfileDialog user={user}>\n <Button variant=\"secondary\">Edit</Button>\n </EditUserProfileDialog>\n </Flex>\n </DataList.Value>\n </DataList.Item>\n\n <ListSeparator />\n\n <DataList.Item align=\"center\">\n <DataList.Label highContrast>\n <Strong>Email address</Strong>\n </DataList.Label>\n <DataList.Value>\n <Flex align=\"center\" minHeight=\"var(--space-6)\">\n <Text size=\"2\">{user.email}</Text>\n </Flex>\n </DataList.Value>\n </DataList.Item>\n\n {oauthAccounts.length > 0 && (\n <>\n <ListSeparator />\n\n <DataList.Item>\n <DataList.Label highContrast>\n <Strong>Connected accounts</Strong>\n </DataList.Label>\n <DataList.Value>\n <Flex direction=\"column\" gap=\"2\">\n {oauthAccounts.map(([account, data]) => (\n <OAuthAccount\n key={account}\n account={account}\n email={data?.email}\n />\n ))}\n </Flex>\n </DataList.Value>\n </DataList.Item>\n </>\n )}\n </DataList.Root>\n </Card>\n );\n};\n\ninterface UserProfileLoadingProps extends WidgetRootDomProps {}\n\nconst UserProfileLoading: React.FC<UserProfileLoadingProps> = (props) => {\n return (\n <Card size=\"2\" {...getWidgetRootDomProps(\"loading\", props)}>\n <DataList.Root>\n <DataList.Item align=\"center\">\n <DataList.Label minWidth=\"220px\" highContrast>\n <Strong>\n <Skeleton>Full name</Skeleton>\n </Strong>\n </DataList.Label>\n <DataList.Value>\n <Flex\n align=\"center\"\n justify=\"between\"\n width=\"100%\"\n minHeight=\"var(--space-6)\"\n >\n <Text size=\"2\">\n <Skeleton>Full name</Skeleton>\n </Text>\n </Flex>\n </DataList.Value>\n </DataList.Item>\n\n <ListSeparator />\n\n <DataList.Item align=\"center\">\n <DataList.Label highContrast>\n <Strong>\n <Skeleton>Email address</Skeleton>\n </Strong>\n </DataList.Label>\n <DataList.Value>\n <Flex align=\"center\" minHeight=\"var(--space-6)\">\n <Text size=\"2\">\n <Skeleton>Email address</Skeleton>\n </Text>\n </Flex>\n </DataList.Value>\n </DataList.Item>\n </DataList.Root>\n </Card>\n );\n};\n\ninterface UserProfileErrorProps extends WidgetRootDomProps {\n error: unknown;\n}\n\nconst UserProfileError: React.FC<UserProfileErrorProps> = ({\n error,\n ...domProps\n}) => {\n return (\n <Card size=\"2\" {...getWidgetRootDomProps(\"error\", domProps)}>\n <GenericError error={error} />\n </Card>\n );\n};\n\nconst ListSeparator = () => (\n <Box asChild gridColumn=\"span 2\">\n <Inset side=\"x\">\n <Separator size=\"4\" />\n </Inset>\n </Box>\n);\n\nconst OAuthAccount = ({\n account,\n email,\n}: {\n account: OAuthAccount;\n email?: string | null;\n}) => {\n const name = getOAuthName(account);\n return (\n <Flex align=\"center\" gap=\"1\">\n <OAuthIcon account={account} />\n <Text size=\"2\" ml=\"1\">\n {name}\n </Text>\n {email && (\n <Box display={{ initial: \"none\", sm: \"contents\" }}>\n <Text size=\"2\" color=\"gray\">\n ∙\n </Text>\n <Text size=\"2\" color=\"gray\">\n {email}\n </Text>\n </Box>\n )}\n </Flex>\n );\n};\n\nconst FallbackUserIcon = () => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"20\"\n height=\"20\"\n fill=\"currentColor\"\n viewBox=\"0 0 256 256\"\n >\n <title>User icon</title>\n <path d=\"M229.19,213c-15.81-27.32-40.63-46.49-69.47-54.62a70,70,0,1,0-63.44,0C67.44,166.5,42.62,185.67,26.81,213a6,6,0,1,0,10.38,6C56.4,185.81,90.34,166,128,166s71.6,19.81,90.81,53a6,6,0,1,0,10.38-6ZM70,96a58,58,0,1,1,58,58A58.07,58.07,0,0,1,70,96Z\" />\n </svg>\n);\n\nfunction getWidgetRootDomProps(\n state: WidgetRootState,\n domProps: WidgetRootDomProps,\n) {\n return getDomProps({\n ...domProps,\n isWidgetRoot: true,\n widgetId: \"user-profile\",\n widgetState: state,\n });\n}\n\nexport type {\n UserProfileProps,\n UserProfileLoadingProps,\n UserProfileErrorProps,\n};\nexport { UserProfile, UserProfileLoading, UserProfileError };\n"],"mappings":"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","names":[]}
@@ -2,6 +2,18 @@ import { AuthenticationInformationResponseData } from '../api/endpoint.js';
2
2
  import { WidgetRootDomProps } from './utils.js';
3
3
  import '@tanstack/react-query';
4
4
  import '../api/widgets-api-client.js';
5
+ import './elements.js';
6
+ import 'react';
7
+ import '@radix-ui/themes';
8
+ import '@radix-ui/themes/props';
9
+ import '../dialog-C15qCLN3.js';
10
+ import '@radix-ui/themes/components/dialog';
11
+ import '../alert-dialog-BlG3_awx.js';
12
+ import '@radix-ui/themes/components/alert-dialog';
13
+ import '../dropdown-menu-BQ5LtvdR.js';
14
+ import '@radix-ui/themes/components/dropdown-menu';
15
+ import '../select-KR89Qnvm.js';
16
+ import '@radix-ui/themes/components/select';
5
17
 
6
18
  interface UserSecurityProps extends WidgetRootDomProps {
7
19
  settings: AuthenticationInformationResponseData;
@@ -1,7 +1,7 @@
1
1
  "use client";
2
2
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
3
3
  import { Card, Flex, Grid, Text } from "@radix-ui/themes";
4
- import { SecondaryButton, Skeleton } from "./elements.js";
4
+ import { Button, Skeleton } from "./elements.js";
5
5
  import { IconPanel } from "./icon-panel.js";
6
6
  import { ButtonIcon, LockClosedIcon } from "@radix-ui/react-icons";
7
7
  import { SetPasswordDialog } from "./set-password-dialog.js";
@@ -44,7 +44,7 @@ const UserSecurityLoading = (props) => {
44
44
  /* @__PURE__ */ jsx(Text, { size: "2", highContrast: true, weight: "bold", as: "p", mb: "-2px", children: /* @__PURE__ */ jsx(Skeleton, { children: "Password" }) }),
45
45
  /* @__PURE__ */ jsx(Text, { as: "p", size: "2", color: "gray", children: /* @__PURE__ */ jsx(Skeleton, { children: "Set a password to access your account" }) })
46
46
  ] }),
47
- /* @__PURE__ */ jsx(ChangePasswordDialog, { children: /* @__PURE__ */ jsx(Skeleton, { children: /* @__PURE__ */ jsx(SecondaryButton, { children: "Change" }) }) })
47
+ /* @__PURE__ */ jsx(ChangePasswordDialog, { children: /* @__PURE__ */ jsx(Skeleton, { children: /* @__PURE__ */ jsx(Button, { variant: "secondary", children: "Change" }) }) })
48
48
  ] }) });
49
49
  };
50
50
  function PasswordSettings({
@@ -63,7 +63,7 @@ function PasswordSettings({
63
63
  )
64
64
  ] }) : /* @__PURE__ */ jsx(Text, { as: "p", size: "2", color: "gray", children: "Set a password to access your account" })
65
65
  ] }),
66
- settings.isSetUp ? /* @__PURE__ */ jsx(ChangePasswordDialog, { children: /* @__PURE__ */ jsx(SecondaryButton, { children: "Change" }) }) : /* @__PURE__ */ jsx(SetPasswordDialog, { children: /* @__PURE__ */ jsx(SecondaryButton, { children: "Set a password" }) })
66
+ settings.isSetUp ? /* @__PURE__ */ jsx(ChangePasswordDialog, { children: /* @__PURE__ */ jsx(Button, { variant: "secondary", children: "Change" }) }) : /* @__PURE__ */ jsx(SetPasswordDialog, { children: /* @__PURE__ */ jsx(Button, { variant: "secondary", children: "Set a password" }) })
67
67
  ] });
68
68
  }
69
69
  function MfaSettings({
@@ -89,7 +89,7 @@ function MfaSettings({
89
89
  ] })
90
90
  ] }) : /* @__PURE__ */ jsx(Text, { as: "p", size: "2", color: "gray", children: "Secure your account with an extra verification step" })
91
91
  ] }),
92
- settings.isSetUp ? /* @__PURE__ */ jsx(ResetMfaDialog, { isPasswordSet, children: /* @__PURE__ */ jsx(SecondaryButton, { children: "Disable" }) }) : /* @__PURE__ */ jsx(AddMfaDialog, { children: /* @__PURE__ */ jsx(SecondaryButton, { children: "Set up authenticator app" }) })
92
+ settings.isSetUp ? /* @__PURE__ */ jsx(ResetMfaDialog, { isPasswordSet, children: /* @__PURE__ */ jsx(Button, { variant: "secondary", children: "Disable" }) }) : /* @__PURE__ */ jsx(AddMfaDialog, { children: /* @__PURE__ */ jsx(Button, { variant: "secondary", children: "Set up authenticator app" }) })
93
93
  ] });
94
94
  }
95
95
  function getWidgetRootDomProps(state, domProps) {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/lib/user-security.tsx"],"sourcesContent":["\"use client\";\n\nimport { Card, Flex, Grid, Text } from \"@radix-ui/themes\";\nimport { SecondaryButton, Skeleton } from \"./elements.js\";\nimport { IconPanel } from \"./icon-panel.js\";\nimport { ButtonIcon, LockClosedIcon } from \"@radix-ui/react-icons\";\nimport { SetPasswordDialog } from \"./set-password-dialog.js\";\nimport { ChangePasswordDialog } from \"./change-password-dialog.js\";\nimport { AddMfaDialog } from \"./add-mfa-dialog.js\";\nimport type {\n AuthenticationInformationResponseData as AuthenticationSettings,\n AuthenticationInformationResponseDataVerificationMethodsPassword as PasswordVerificationMethod,\n AuthenticationInformationResponseDataVerificationMethodsMfa as MfaVerificationMethod,\n} from \"../api/endpoint.js\";\nimport { ResetMfaDialog } from \"./reset-mfa-dialog.js\";\nimport * as CardList from \"./card-list.js\";\nimport { GenericError } from \"./generic-error.js\";\nimport {\n getComparativeReadableDate,\n getDomProps,\n type WidgetRootDomProps,\n type WidgetRootState,\n} from \"./utils.js\";\n\ninterface UserSecurityProps extends WidgetRootDomProps {\n settings: AuthenticationSettings;\n}\n\nconst UserSecurity: React.FC<UserSecurityProps> = ({\n settings,\n ...domProps\n}) => {\n const passwordSettings = settings.verificationMethods.Password;\n const mfaSettings = settings.verificationMethods.Mfa;\n return (\n <CardList.Root {...getWidgetRootDomProps(\"resolved\", domProps)}>\n {passwordSettings && (\n <CardList.Item>\n <PasswordSettings settings={passwordSettings} />\n </CardList.Item>\n )}\n {mfaSettings && (\n <CardList.Item>\n <MfaSettings\n settings={mfaSettings}\n isPasswordSet={!!passwordSettings?.isSetUp}\n />\n </CardList.Item>\n )}\n </CardList.Root>\n );\n};\n\ninterface UserSecurityErrorProps extends WidgetRootDomProps {\n error: unknown;\n}\n\nconst UserSecurityError: React.FC<UserSecurityErrorProps> = ({\n error,\n ...domProps\n}) => {\n return (\n <Card size=\"2\" {...getWidgetRootDomProps(\"error\", domProps)}>\n <GenericError error={error} />\n </Card>\n );\n};\n\ninterface UserSecurityLoadingProps extends WidgetRootDomProps {}\n\nconst UserSecurityLoading: React.FC<UserSecurityLoadingProps> = (props) => {\n return (\n <Card size=\"2\" {...getWidgetRootDomProps(\"loading\", props)}>\n <Grid columns=\"auto 1fr auto\" align=\"center\" gap=\"4\">\n <Skeleton>\n <IconPanel />\n </Skeleton>\n\n <Flex direction=\"column\">\n <Text size=\"2\" highContrast weight=\"bold\" as=\"p\" mb=\"-2px\">\n <Skeleton>Password</Skeleton>\n </Text>\n <Text as=\"p\" size=\"2\" color=\"gray\">\n <Skeleton>Set a password to access your account</Skeleton>\n </Text>\n </Flex>\n\n <ChangePasswordDialog>\n <Skeleton>\n <SecondaryButton>Change</SecondaryButton>\n </Skeleton>\n </ChangePasswordDialog>\n </Grid>\n </Card>\n );\n};\n\nfunction PasswordSettings({\n settings,\n}: {\n settings: NonNullable<PasswordVerificationMethod>;\n}) {\n return (\n <Grid columns=\"auto 1fr auto\" align=\"center\" gap=\"4\">\n <IconPanel>\n <LockClosedIcon />\n </IconPanel>\n\n <Flex direction=\"column\">\n <Text size=\"2\" highContrast weight=\"bold\" as=\"p\" mb=\"-2px\">\n Password\n </Text>\n\n {settings.isSetUp ? (\n settings.lastUsed && (\n <Text size=\"2\" color=\"gray\">\n Last used{\" \"}\n {getComparativeReadableDate(\n new Date(),\n new Date(settings.lastUsed),\n )}\n </Text>\n )\n ) : (\n <Text as=\"p\" size=\"2\" color=\"gray\">\n Set a password to access your account\n </Text>\n )}\n </Flex>\n\n {settings.isSetUp ? (\n <ChangePasswordDialog>\n <SecondaryButton>Change</SecondaryButton>\n </ChangePasswordDialog>\n ) : (\n <SetPasswordDialog>\n <SecondaryButton>Set a password</SecondaryButton>\n </SetPasswordDialog>\n )}\n </Grid>\n );\n}\n\nfunction MfaSettings({\n settings,\n isPasswordSet,\n}: {\n settings: NonNullable<MfaVerificationMethod>;\n isPasswordSet: boolean;\n}) {\n return (\n <Grid columns=\"auto 1fr auto\" align=\"center\" gap=\"4\">\n <IconPanel>\n <ButtonIcon />\n </IconPanel>\n\n <Flex direction=\"column\">\n <Text size=\"2\" highContrast weight=\"bold\" as=\"p\" mb=\"-2px\">\n Multi-factor authentication\n </Text>\n\n {settings.isSetUp ? (\n <Text size=\"2\">\n Authenticator app\n {settings.lastUsed && (\n <>\n <Text size=\"2\" color=\"gray\" mx=\"1\">\n ∙\n </Text>\n <Text size=\"2\" color=\"gray\">\n Last used{\" \"}\n {getComparativeReadableDate(\n new Date(),\n new Date(settings.lastUsed),\n )}\n </Text>\n </>\n )}\n </Text>\n ) : (\n <Text as=\"p\" size=\"2\" color=\"gray\">\n Secure your account with an extra verification step\n </Text>\n )}\n </Flex>\n\n {settings.isSetUp ? (\n <ResetMfaDialog isPasswordSet={isPasswordSet}>\n <SecondaryButton>Disable</SecondaryButton>\n </ResetMfaDialog>\n ) : (\n <AddMfaDialog>\n <SecondaryButton>Set up authenticator app</SecondaryButton>\n </AddMfaDialog>\n )}\n </Grid>\n );\n}\n\nfunction getWidgetRootDomProps(\n state: WidgetRootState,\n domProps: WidgetRootDomProps,\n) {\n return getDomProps({\n ...domProps,\n isWidgetRoot: true,\n widgetId: \"user-security\",\n widgetState: state,\n });\n}\n\nexport type {\n UserSecurityProps,\n UserSecurityLoadingProps,\n UserSecurityErrorProps,\n};\nexport { UserSecurity, UserSecurityLoading, UserSecurityError };\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../../src/lib/user-security.tsx"],"sourcesContent":["\"use client\";\n\nimport { Card, Flex, Grid, Text } from \"@radix-ui/themes\";\nimport { Button, Skeleton } from \"./elements.js\";\nimport { IconPanel } from \"./icon-panel.js\";\nimport { ButtonIcon, LockClosedIcon } from \"@radix-ui/react-icons\";\nimport { SetPasswordDialog } from \"./set-password-dialog.js\";\nimport { ChangePasswordDialog } from \"./change-password-dialog.js\";\nimport { AddMfaDialog } from \"./add-mfa-dialog.js\";\nimport type {\n AuthenticationInformationResponseData as AuthenticationSettings,\n AuthenticationInformationResponseDataVerificationMethodsPassword as PasswordVerificationMethod,\n AuthenticationInformationResponseDataVerificationMethodsMfa as MfaVerificationMethod,\n} from \"../api/endpoint.js\";\nimport { ResetMfaDialog } from \"./reset-mfa-dialog.js\";\nimport * as CardList from \"./card-list.js\";\nimport { GenericError } from \"./generic-error.js\";\nimport {\n getComparativeReadableDate,\n getDomProps,\n type WidgetRootDomProps,\n type WidgetRootState,\n} from \"./utils.js\";\n\ninterface UserSecurityProps extends WidgetRootDomProps {\n settings: AuthenticationSettings;\n}\n\nconst UserSecurity: React.FC<UserSecurityProps> = ({\n settings,\n ...domProps\n}) => {\n const passwordSettings = settings.verificationMethods.Password;\n const mfaSettings = settings.verificationMethods.Mfa;\n return (\n <CardList.Root {...getWidgetRootDomProps(\"resolved\", domProps)}>\n {passwordSettings && (\n <CardList.Item>\n <PasswordSettings settings={passwordSettings} />\n </CardList.Item>\n )}\n {mfaSettings && (\n <CardList.Item>\n <MfaSettings\n settings={mfaSettings}\n isPasswordSet={!!passwordSettings?.isSetUp}\n />\n </CardList.Item>\n )}\n </CardList.Root>\n );\n};\n\ninterface UserSecurityErrorProps extends WidgetRootDomProps {\n error: unknown;\n}\n\nconst UserSecurityError: React.FC<UserSecurityErrorProps> = ({\n error,\n ...domProps\n}) => {\n return (\n <Card size=\"2\" {...getWidgetRootDomProps(\"error\", domProps)}>\n <GenericError error={error} />\n </Card>\n );\n};\n\ninterface UserSecurityLoadingProps extends WidgetRootDomProps {}\n\nconst UserSecurityLoading: React.FC<UserSecurityLoadingProps> = (props) => {\n return (\n <Card size=\"2\" {...getWidgetRootDomProps(\"loading\", props)}>\n <Grid columns=\"auto 1fr auto\" align=\"center\" gap=\"4\">\n <Skeleton>\n <IconPanel />\n </Skeleton>\n\n <Flex direction=\"column\">\n <Text size=\"2\" highContrast weight=\"bold\" as=\"p\" mb=\"-2px\">\n <Skeleton>Password</Skeleton>\n </Text>\n <Text as=\"p\" size=\"2\" color=\"gray\">\n <Skeleton>Set a password to access your account</Skeleton>\n </Text>\n </Flex>\n\n <ChangePasswordDialog>\n <Skeleton>\n <Button variant=\"secondary\">Change</Button>\n </Skeleton>\n </ChangePasswordDialog>\n </Grid>\n </Card>\n );\n};\n\nfunction PasswordSettings({\n settings,\n}: {\n settings: NonNullable<PasswordVerificationMethod>;\n}) {\n return (\n <Grid columns=\"auto 1fr auto\" align=\"center\" gap=\"4\">\n <IconPanel>\n <LockClosedIcon />\n </IconPanel>\n\n <Flex direction=\"column\">\n <Text size=\"2\" highContrast weight=\"bold\" as=\"p\" mb=\"-2px\">\n Password\n </Text>\n\n {settings.isSetUp ? (\n settings.lastUsed && (\n <Text size=\"2\" color=\"gray\">\n Last used{\" \"}\n {getComparativeReadableDate(\n new Date(),\n new Date(settings.lastUsed),\n )}\n </Text>\n )\n ) : (\n <Text as=\"p\" size=\"2\" color=\"gray\">\n Set a password to access your account\n </Text>\n )}\n </Flex>\n\n {settings.isSetUp ? (\n <ChangePasswordDialog>\n <Button variant=\"secondary\">Change</Button>\n </ChangePasswordDialog>\n ) : (\n <SetPasswordDialog>\n <Button variant=\"secondary\">Set a password</Button>\n </SetPasswordDialog>\n )}\n </Grid>\n );\n}\n\nfunction MfaSettings({\n settings,\n isPasswordSet,\n}: {\n settings: NonNullable<MfaVerificationMethod>;\n isPasswordSet: boolean;\n}) {\n return (\n <Grid columns=\"auto 1fr auto\" align=\"center\" gap=\"4\">\n <IconPanel>\n <ButtonIcon />\n </IconPanel>\n\n <Flex direction=\"column\">\n <Text size=\"2\" highContrast weight=\"bold\" as=\"p\" mb=\"-2px\">\n Multi-factor authentication\n </Text>\n\n {settings.isSetUp ? (\n <Text size=\"2\">\n Authenticator app\n {settings.lastUsed && (\n <>\n <Text size=\"2\" color=\"gray\" mx=\"1\">\n ∙\n </Text>\n <Text size=\"2\" color=\"gray\">\n Last used{\" \"}\n {getComparativeReadableDate(\n new Date(),\n new Date(settings.lastUsed),\n )}\n </Text>\n </>\n )}\n </Text>\n ) : (\n <Text as=\"p\" size=\"2\" color=\"gray\">\n Secure your account with an extra verification step\n </Text>\n )}\n </Flex>\n\n {settings.isSetUp ? (\n <ResetMfaDialog isPasswordSet={isPasswordSet}>\n <Button variant=\"secondary\">Disable</Button>\n </ResetMfaDialog>\n ) : (\n <AddMfaDialog>\n <Button variant=\"secondary\">Set up authenticator app</Button>\n </AddMfaDialog>\n )}\n </Grid>\n );\n}\n\nfunction getWidgetRootDomProps(\n state: WidgetRootState,\n domProps: WidgetRootDomProps,\n) {\n return getDomProps({\n ...domProps,\n isWidgetRoot: true,\n widgetId: \"user-security\",\n widgetState: state,\n });\n}\n\nexport type {\n UserSecurityProps,\n UserSecurityLoadingProps,\n UserSecurityErrorProps,\n};\nexport { UserSecurity, UserSecurityLoading, UserSecurityError };\n"],"mappings":"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","names":[]}
@@ -1,6 +1,18 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import { WidgetRootDomProps } from './utils.js';
3
3
  import { ActiveSession } from '../api/endpoint.js';
4
+ import './elements.js';
5
+ import 'react';
6
+ import '@radix-ui/themes';
7
+ import '@radix-ui/themes/props';
8
+ import '../dialog-C15qCLN3.js';
9
+ import '@radix-ui/themes/components/dialog';
10
+ import '../alert-dialog-BlG3_awx.js';
11
+ import '@radix-ui/themes/components/alert-dialog';
12
+ import '../dropdown-menu-BQ5LtvdR.js';
13
+ import '@radix-ui/themes/components/dropdown-menu';
14
+ import '../select-KR89Qnvm.js';
15
+ import '@radix-ui/themes/components/select';
4
16
  import '@tanstack/react-query';
5
17
  import '../api/widgets-api-client.js';
6
18
 
@@ -1,7 +1,7 @@
1
1
  "use client";
2
2
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
3
- import { Box, Button, Card, Flex, Text } from "@radix-ui/themes";
4
- import { Badge, SecondaryButton, Skeleton } from "./elements.js";
3
+ import { Box, Card, Flex, Text } from "@radix-ui/themes";
4
+ import { Badge, Button, Skeleton } from "./elements.js";
5
5
  import {
6
6
  getComparativeReadableDate,
7
7
  getDomProps,
@@ -55,8 +55,9 @@ const UserSessions = ({
55
55
  /* @__PURE__ */ jsx(Text, { size: "2", color: "gray", as: "p", children: "Remove access from all devices except this one" })
56
56
  ] }),
57
57
  /* @__PURE__ */ jsx(
58
- SecondaryButton,
58
+ Button,
59
59
  {
60
+ variant: "secondary",
60
61
  onClick: () => {
61
62
  setOpenLogoutAllSessionsDialog(true);
62
63
  },
@@ -129,16 +130,7 @@ const UserSession = ({
129
130
  ] })
130
131
  ] })
131
132
  ] }),
132
- !isCurrentSession && /* @__PURE__ */ jsx(Flex, { ml: "auto", mr: "2", children: /* @__PURE__ */ jsx(
133
- Button,
134
- {
135
- variant: "ghost",
136
- onClick: () => {
137
- onSignOut?.(session);
138
- },
139
- children: "Sign out"
140
- }
141
- ) })
133
+ !isCurrentSession && /* @__PURE__ */ jsx(Flex, { ml: "auto", children: /* @__PURE__ */ jsx(Button, { variant: "secondary", onClick: () => onSignOut?.(session), children: "Sign out" }) })
142
134
  ] });
143
135
  };
144
136
  function getWidgetRootDomProps(state, domProps) {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/lib/user-sessions.tsx"],"sourcesContent":["\"use client\";\n\nimport { Box, Button, Card, Flex, Text } from \"@radix-ui/themes\";\nimport { Badge, SecondaryButton, Skeleton } from \"./elements.js\";\nimport {\n getComparativeReadableDate,\n getDomProps,\n getUserLocation,\n parseUserAgent,\n type WidgetRootDomProps,\n type WidgetRootState,\n} from \"./utils.js\";\nimport { LogoutDialog } from \"./logout-dialog.js\";\nimport { LogoutAllSessionsDialog } from \"./logout-all-sessions-dialog.js\";\nimport { ActiveSession } from \"../api/endpoint.js\";\nimport * as CardList from \"./card-list.js\";\nimport { IconPanel } from \"./icon-panel.js\";\nimport { useState } from \"react\";\nimport { GenericError } from \"./generic-error.js\";\nimport { LaptopIcon, MobileIcon } from \"@radix-ui/react-icons\";\n\ninterface UserSessionsProps extends WidgetRootDomProps {\n sessionsData: ActiveSession[];\n currentSessionId: string;\n}\n\nconst UserSessions = ({\n sessionsData: sessions,\n currentSessionId,\n ...domProps\n}: UserSessionsProps) => {\n const currentSession = sessions.find(\n (session) => session.id === currentSessionId,\n );\n const otherSessions = sessions.filter(\n (session) => session.id !== currentSessionId,\n );\n const [openLogoutDialog, setOpenLogoutDialog] = useState(false);\n const [sessionToSignOut, setSessionToSignOut] =\n useState<ActiveSession | null>(null);\n const [openLogoutAllSessionsDialog, setOpenLogoutAllSessionsDialog] =\n useState(false);\n\n return (\n <Flex\n direction=\"column\"\n gap=\"4\"\n {...getWidgetRootDomProps(\"resolved\", domProps)}\n >\n <CardList.Root>\n {currentSession && (\n <CardList.Item>\n <UserSession session={currentSession} isCurrentSession />\n </CardList.Item>\n )}\n\n {otherSessions.map((session) => (\n <CardList.Item key={session.id}>\n <UserSession\n session={session}\n onSignOut={() => {\n setSessionToSignOut(session);\n setOpenLogoutDialog(true);\n }}\n />\n </CardList.Item>\n ))}\n </CardList.Root>\n\n {sessions.length > 1 && (\n <Card size=\"2\">\n <Flex gap=\"2\" justify=\"between\" align=\"center\">\n <Box>\n <Text size=\"2\" highContrast weight=\"bold\" as=\"p\">\n Sign out of all other devices\n </Text>\n <Text size=\"2\" color=\"gray\" as=\"p\">\n Remove access from all devices except this one\n </Text>\n </Box>\n\n <SecondaryButton\n onClick={() => {\n setOpenLogoutAllSessionsDialog(true);\n }}\n >\n Sign out\n </SecondaryButton>\n </Flex>\n </Card>\n )}\n\n {sessionToSignOut && (\n <LogoutDialog\n session={sessionToSignOut}\n open={openLogoutDialog}\n onOpenChange={setOpenLogoutDialog}\n />\n )}\n\n <LogoutAllSessionsDialog\n currentSessionId={currentSessionId}\n open={openLogoutAllSessionsDialog}\n onOpenChange={setOpenLogoutAllSessionsDialog}\n />\n </Flex>\n );\n};\n\ninterface UserSessionsLoadingProps extends WidgetRootDomProps {}\n\nconst UserSessionsLoading: React.FC<UserSessionsLoadingProps> = (props) => {\n return (\n <Card size=\"2\" {...getWidgetRootDomProps(\"loading\", props)}>\n <Flex gap=\"4\" align=\"center\">\n <Skeleton>\n <IconPanel />\n </Skeleton>\n\n <Flex direction=\"column\">\n <Text size=\"2\" highContrast weight=\"bold\" as=\"p\" mb=\"-2px\">\n <Skeleton>The location</Skeleton>\n </Text>\n\n <Text size=\"2\" color=\"gray\" as=\"p\">\n <Skeleton>The location</Skeleton>\n </Text>\n </Flex>\n </Flex>\n </Card>\n );\n};\n\ninterface UserSessionsErrorProps extends WidgetRootDomProps {\n error: unknown;\n}\n\nconst UserSessionsError: React.FC<UserSessionsErrorProps> = ({\n error,\n ...domProps\n}) => {\n return (\n <Card size=\"2\" {...getWidgetRootDomProps(\"error\", domProps)}>\n <GenericError error={error} />\n </Card>\n );\n};\n\ninterface UserSessionProps {\n session: ActiveSession;\n isCurrentSession?: boolean;\n onSignOut?: (session: ActiveSession) => void;\n}\n\nconst UserSession = ({\n session,\n isCurrentSession = false,\n onSignOut,\n}: UserSessionProps) => {\n const userAgent = parseUserAgent(session.userAgent);\n const userLocation = getUserLocation(\n session.currentLocation,\n session.ipAddress,\n );\n\n return (\n <Flex gap=\"4\" align=\"center\">\n <IconPanel>\n {userAgent.isMobile ? <MobileIcon /> : <LaptopIcon />}\n </IconPanel>\n\n <Flex direction=\"column\">\n <Text size=\"2\" highContrast weight=\"bold\" as=\"p\" mb=\"-2px\">\n {userAgent.pretty}\n </Text>\n\n <Flex gap=\"1\" align=\"center\">\n <Text size=\"2\" color=\"gray\" as=\"p\">\n {userLocation}\n </Text>\n\n {isCurrentSession && <Badge ml=\"2\">This device</Badge>}\n\n {!isCurrentSession && session.lastActivityAt && (\n <>\n <Text size=\"2\" color=\"gray\">\n ∙\n </Text>\n <Text size=\"2\" color=\"gray\">\n Last seen{\" \"}\n {getComparativeReadableDate(\n new Date(),\n new Date(session.lastActivityAt),\n )}\n </Text>\n </>\n )}\n </Flex>\n </Flex>\n\n {!isCurrentSession && (\n <Flex ml=\"auto\" mr=\"2\">\n <Button\n variant=\"ghost\"\n onClick={() => {\n onSignOut?.(session);\n }}\n >\n Sign out\n </Button>\n </Flex>\n )}\n </Flex>\n );\n};\n\nfunction getWidgetRootDomProps(\n state: WidgetRootState,\n domProps: WidgetRootDomProps,\n) {\n return getDomProps({\n ...domProps,\n isWidgetRoot: true,\n widgetId: \"user-sessions\",\n widgetState: state,\n });\n}\n\nexport type { UserSessionsLoadingProps, UserSessionsErrorProps };\nexport { UserSessions, UserSessionsLoading, UserSessionsError };\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../../src/lib/user-sessions.tsx"],"sourcesContent":["\"use client\";\n\nimport { Box, Card, Flex, Text } from \"@radix-ui/themes\";\nimport { Badge, Button, Skeleton } from \"./elements.js\";\nimport {\n getComparativeReadableDate,\n getDomProps,\n getUserLocation,\n parseUserAgent,\n type WidgetRootDomProps,\n type WidgetRootState,\n} from \"./utils.js\";\nimport { LogoutDialog } from \"./logout-dialog.js\";\nimport { LogoutAllSessionsDialog } from \"./logout-all-sessions-dialog.js\";\nimport { ActiveSession } from \"../api/endpoint.js\";\nimport * as CardList from \"./card-list.js\";\nimport { IconPanel } from \"./icon-panel.js\";\nimport { useState } from \"react\";\nimport { GenericError } from \"./generic-error.js\";\nimport { LaptopIcon, MobileIcon } from \"@radix-ui/react-icons\";\n\ninterface UserSessionsProps extends WidgetRootDomProps {\n sessionsData: ActiveSession[];\n currentSessionId: string;\n}\n\nconst UserSessions = ({\n sessionsData: sessions,\n currentSessionId,\n ...domProps\n}: UserSessionsProps) => {\n const currentSession = sessions.find(\n (session) => session.id === currentSessionId,\n );\n const otherSessions = sessions.filter(\n (session) => session.id !== currentSessionId,\n );\n const [openLogoutDialog, setOpenLogoutDialog] = useState(false);\n const [sessionToSignOut, setSessionToSignOut] =\n useState<ActiveSession | null>(null);\n const [openLogoutAllSessionsDialog, setOpenLogoutAllSessionsDialog] =\n useState(false);\n\n return (\n <Flex\n direction=\"column\"\n gap=\"4\"\n {...getWidgetRootDomProps(\"resolved\", domProps)}\n >\n <CardList.Root>\n {currentSession && (\n <CardList.Item>\n <UserSession session={currentSession} isCurrentSession />\n </CardList.Item>\n )}\n\n {otherSessions.map((session) => (\n <CardList.Item key={session.id}>\n <UserSession\n session={session}\n onSignOut={() => {\n setSessionToSignOut(session);\n setOpenLogoutDialog(true);\n }}\n />\n </CardList.Item>\n ))}\n </CardList.Root>\n\n {sessions.length > 1 && (\n <Card size=\"2\">\n <Flex gap=\"2\" justify=\"between\" align=\"center\">\n <Box>\n <Text size=\"2\" highContrast weight=\"bold\" as=\"p\">\n Sign out of all other devices\n </Text>\n <Text size=\"2\" color=\"gray\" as=\"p\">\n Remove access from all devices except this one\n </Text>\n </Box>\n <Button\n variant=\"secondary\"\n onClick={() => {\n setOpenLogoutAllSessionsDialog(true);\n }}\n >\n Sign out\n </Button>\n </Flex>\n </Card>\n )}\n\n {sessionToSignOut && (\n <LogoutDialog\n session={sessionToSignOut}\n open={openLogoutDialog}\n onOpenChange={setOpenLogoutDialog}\n />\n )}\n\n <LogoutAllSessionsDialog\n currentSessionId={currentSessionId}\n open={openLogoutAllSessionsDialog}\n onOpenChange={setOpenLogoutAllSessionsDialog}\n />\n </Flex>\n );\n};\n\ninterface UserSessionsLoadingProps extends WidgetRootDomProps {}\n\nconst UserSessionsLoading: React.FC<UserSessionsLoadingProps> = (props) => {\n return (\n <Card size=\"2\" {...getWidgetRootDomProps(\"loading\", props)}>\n <Flex gap=\"4\" align=\"center\">\n <Skeleton>\n <IconPanel />\n </Skeleton>\n\n <Flex direction=\"column\">\n <Text size=\"2\" highContrast weight=\"bold\" as=\"p\" mb=\"-2px\">\n <Skeleton>The location</Skeleton>\n </Text>\n\n <Text size=\"2\" color=\"gray\" as=\"p\">\n <Skeleton>The location</Skeleton>\n </Text>\n </Flex>\n </Flex>\n </Card>\n );\n};\n\ninterface UserSessionsErrorProps extends WidgetRootDomProps {\n error: unknown;\n}\n\nconst UserSessionsError: React.FC<UserSessionsErrorProps> = ({\n error,\n ...domProps\n}) => {\n return (\n <Card size=\"2\" {...getWidgetRootDomProps(\"error\", domProps)}>\n <GenericError error={error} />\n </Card>\n );\n};\n\ninterface UserSessionProps {\n session: ActiveSession;\n isCurrentSession?: boolean;\n onSignOut?: (session: ActiveSession) => void;\n}\n\nconst UserSession = ({\n session,\n isCurrentSession = false,\n onSignOut,\n}: UserSessionProps) => {\n const userAgent = parseUserAgent(session.userAgent);\n const userLocation = getUserLocation(\n session.currentLocation,\n session.ipAddress,\n );\n\n return (\n <Flex gap=\"4\" align=\"center\">\n <IconPanel>\n {userAgent.isMobile ? <MobileIcon /> : <LaptopIcon />}\n </IconPanel>\n\n <Flex direction=\"column\">\n <Text size=\"2\" highContrast weight=\"bold\" as=\"p\" mb=\"-2px\">\n {userAgent.pretty}\n </Text>\n\n <Flex gap=\"1\" align=\"center\">\n <Text size=\"2\" color=\"gray\" as=\"p\">\n {userLocation}\n </Text>\n\n {isCurrentSession && <Badge ml=\"2\">This device</Badge>}\n\n {!isCurrentSession && session.lastActivityAt && (\n <>\n <Text size=\"2\" color=\"gray\">\n ∙\n </Text>\n <Text size=\"2\" color=\"gray\">\n Last seen{\" \"}\n {getComparativeReadableDate(\n new Date(),\n new Date(session.lastActivityAt),\n )}\n </Text>\n </>\n )}\n </Flex>\n </Flex>\n\n {!isCurrentSession && (\n <Flex ml=\"auto\">\n <Button variant=\"secondary\" onClick={() => onSignOut?.(session)}>\n Sign out\n </Button>\n </Flex>\n )}\n </Flex>\n );\n};\n\nfunction getWidgetRootDomProps(\n state: WidgetRootState,\n domProps: WidgetRootDomProps,\n) {\n return getDomProps({\n ...domProps,\n isWidgetRoot: true,\n widgetId: \"user-sessions\",\n widgetState: state,\n });\n}\n\nexport type { UserSessionsLoadingProps, UserSessionsErrorProps };\nexport { UserSessions, UserSessionsLoading, UserSessionsError };\n"],"mappings":"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","names":[]}
@@ -1,10 +1,10 @@
1
- import { Select } from '@radix-ui/themes';
2
1
  import * as React from 'react';
2
+ import { Root } from '@radix-ui/themes/components/select';
3
3
  import { MemberRole } from '../api/endpoint.js';
4
4
  import '@tanstack/react-query';
5
5
  import '../api/widgets-api-client.js';
6
6
 
7
- type UsersFilterProps = React.ComponentPropsWithoutRef<typeof Select.Root> & {
7
+ type UsersFilterProps = React.ComponentPropsWithoutRef<typeof Root> & {
8
8
  roles: MemberRole[] | undefined;
9
9
  disabled?: boolean;
10
10
  };