@rapidmx/web-client 0.30.0 → 0.32.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 (402) hide show
  1. package/apps/admin/audit-log/index.tsx +3 -3
  2. package/apps/admin/branding/index.tsx +3 -3
  3. package/apps/admin/data-requests/index.tsx +18 -7
  4. package/apps/admin/distribution-lists/[uid].tsx +3 -3
  5. package/apps/admin/distribution-lists/index.tsx +3 -3
  6. package/apps/admin/distribution-lists/new/index.tsx +3 -3
  7. package/apps/admin/domains/[uid].tsx +6 -5
  8. package/apps/admin/domains/index.tsx +3 -3
  9. package/apps/admin/domains/new/index.tsx +3 -3
  10. package/apps/admin/escrow-scopes/[uid].tsx +11 -5
  11. package/apps/admin/escrow-scopes/index.tsx +3 -3
  12. package/apps/admin/escrow-scopes/new/index.tsx +9 -3
  13. package/apps/admin/index.tsx +4 -4
  14. package/apps/admin/ingest-queue/index.tsx +3 -3
  15. package/apps/admin/mailboxes/[uid].tsx +15 -7
  16. package/apps/admin/quarantine/index.tsx +4 -4
  17. package/apps/admin/retention-policy/index.tsx +3 -3
  18. package/apps/admin/signing-certificates/index.tsx +3 -3
  19. package/apps/admin/transport-rules/[uid].tsx +4 -4
  20. package/apps/admin/transport-rules/index.tsx +3 -3
  21. package/apps/admin/transport-rules/new/index.tsx +3 -3
  22. package/apps/escrow/matters/[uid].tsx +26 -2
  23. package/apps/escrow/matters/new/index.tsx +4 -0
  24. package/apps/shared/calendar/calendarLiveUpdates.ts +11 -10
  25. package/apps/shared/calendar/useCalendarReminders.ts +2 -0
  26. package/apps/shared/components/admin/ActionAlert.tsx +32 -0
  27. package/apps/shared/components/admin/diagnostics/InformationPanel.tsx +3 -3
  28. package/apps/shared/components/admin/diagnostics/InstalledPlugins.tsx +1 -1
  29. package/apps/shared/components/admin/diagnostics/LogsPanel.tsx +1 -1
  30. package/apps/shared/components/admin/diagnostics/RuntimePanel.tsx +1 -1
  31. package/apps/shared/components/admin/diagnostics/SystemPanel.tsx +1 -1
  32. package/apps/shared/components/admin/diagnostics/diagnosticsApi.ts +2 -2
  33. package/apps/shared/components/admin/distributionLists/MemberListCard.tsx +4 -4
  34. package/apps/shared/components/admin/elevation.ts +19 -0
  35. package/apps/shared/components/admin/escrowScopes/EscrowScopeKeyAndHoldersFields.tsx +58 -3
  36. package/apps/shared/components/admin/layout/AdminShell.tsx +6 -1
  37. package/apps/shared/components/admin/mailboxes/EraseLeftoverDataDialog.tsx +3 -3
  38. package/apps/shared/components/admin/mailboxes/EscrowScopeCard.tsx +4 -4
  39. package/apps/shared/components/admin/mailboxes/LeftoverMailboxesSection.tsx +4 -4
  40. package/apps/shared/components/admin/mailboxes/ResourceSettingsCard.tsx +3 -3
  41. package/apps/shared/components/admin/mailboxes/ShareAccessCard.tsx +6 -6
  42. package/apps/shared/components/admin/settings/BrandingForm.tsx +22 -9
  43. package/apps/shared/components/admin/settings/DomainDnsSetup.tsx +4 -4
  44. package/apps/shared/components/admin/settings/EncryptionPolicyForm.tsx +33 -4
  45. package/apps/shared/components/admin/settings/LoadedSettingsForm.tsx +3 -3
  46. package/apps/shared/components/admin/settings/MailboxCreateForm.tsx +8 -3
  47. package/apps/shared/components/admin/settings/MailboxPolicyForm.tsx +3 -3
  48. package/apps/shared/components/admin/settings/PluginsManager.tsx +195 -46
  49. package/apps/shared/components/admin/settings/RetentionPolicyForm.tsx +25 -12
  50. package/apps/shared/components/admin/setup/EscrowSetupStep.tsx +40 -7
  51. package/apps/shared/components/admin/setup/SetupWizard.tsx +8 -6
  52. package/apps/shared/components/admin/signOut.ts +3 -0
  53. package/apps/shared/components/admin/usePagedList.tsx +2 -2
  54. package/apps/shared/components/calendar/DescriptionEditor.tsx +2 -1
  55. package/apps/shared/components/calendar/EventDetails.tsx +34 -8
  56. package/apps/shared/components/calendar/EventEditor.tsx +90 -40
  57. package/apps/shared/components/calendar/EventFormParts.tsx +5 -2
  58. package/apps/shared/components/calendar/EventMatchNav.tsx +14 -2
  59. package/apps/shared/components/calendar/EventModal.tsx +25 -1
  60. package/apps/shared/components/calendar/FindATime.tsx +10 -2
  61. package/apps/shared/components/calendar/ListView.tsx +99 -25
  62. package/apps/shared/components/calendar/RecurrenceEditor.tsx +19 -8
  63. package/apps/shared/components/calendar/SplitDayView.tsx +14 -18
  64. package/apps/shared/components/calendar/TaskQuickForm.tsx +3 -2
  65. package/apps/shared/components/calendar/TimeGridView.tsx +35 -19
  66. package/apps/shared/components/calendar/gridLayout.ts +94 -0
  67. package/apps/shared/components/calendar/layout/CalendarShell.tsx +1 -1
  68. package/apps/shared/components/calendar/timePicker.ts +5 -2
  69. package/apps/shared/components/contacts/ContactCard.tsx +15 -4
  70. package/apps/shared/components/contacts/ContactDetailPane.tsx +54 -15
  71. package/apps/shared/components/contacts/ContactForm.tsx +61 -17
  72. package/apps/shared/components/contacts/ContactPhotoEditor.tsx +88 -0
  73. package/apps/shared/components/contacts/ContactPhotoField.tsx +36 -39
  74. package/apps/shared/components/contacts/layout/ContactsShell.tsx +1 -1
  75. package/apps/shared/components/contacts/participantDetails.ts +18 -1
  76. package/apps/shared/components/layout/AppShell.tsx +9 -0
  77. package/apps/shared/components/layout/KeyEnrollmentGate.tsx +9 -4
  78. package/apps/shared/components/layout/MailboxProvisioning.tsx +31 -3
  79. package/apps/shared/components/layout/RecoveryCodeUnlock.tsx +4 -2
  80. package/apps/shared/components/mail/ConversationList.tsx +49 -6
  81. package/apps/shared/components/mail/ConversationThreadPane.tsx +1 -1
  82. package/apps/shared/components/mail/MenuButton.tsx +3 -400
  83. package/apps/shared/components/mail/MessageDetailPane.tsx +16 -13
  84. package/apps/shared/components/mail/compose/ComposeToolbar.tsx +11 -1
  85. package/apps/shared/components/mail/compose/ComposeWindow.tsx +57 -11
  86. package/apps/shared/components/mail/compose/GifPicker.tsx +10 -4
  87. package/apps/shared/components/mail/compose/RecipientInput.tsx +9 -7
  88. package/apps/shared/components/mail/compose/composeFlushRegistry.ts +14 -1
  89. package/apps/shared/components/mail/compose/encryptionRequirement.ts +5 -0
  90. package/apps/shared/components/mail/compose/quotedBody.ts +31 -6
  91. package/apps/shared/components/mail/layout/MailShell.tsx +1 -1
  92. package/apps/shared/components/mail/reading/MessageBody.tsx +13 -7
  93. package/apps/shared/components/mail/reading/bodyContent.ts +2 -0
  94. package/apps/shared/components/mail/reading/bodyHtml.ts +25 -2
  95. package/apps/shared/components/mail/writableMailboxes.ts +2 -0
  96. package/apps/shared/components/rules/RuleBuilder.tsx +11 -2
  97. package/apps/shared/components/settings/GravatarSetting.tsx +27 -0
  98. package/apps/shared/components/settings/layout/SettingsShell.tsx +1 -1
  99. package/apps/shared/components/tasks/dueDate.ts +29 -0
  100. package/apps/shared/components/tasks/layout/TasksShell.tsx +1 -1
  101. package/apps/shared/mail/decryptedMessages.ts +51 -2
  102. package/apps/shared/mail/listSnapshots.ts +2 -0
  103. package/apps/shared/mail/outbox/sendDecision.ts +14 -3
  104. package/apps/shared/mail/outbox/sendJob.ts +5 -0
  105. package/apps/shared/mail/useMailLiveUpdates.ts +7 -1
  106. package/apps/shared/mail/usePermanentDelete.tsx +3 -1
  107. package/apps/shared/notifications/apiErrors.ts +2 -0
  108. package/apps/shared/notifications/preferences.ts +1 -1
  109. package/apps/shared/notifications/store.ts +3 -1
  110. package/apps/shared/plugins/pluginNav.ts +4 -2
  111. package/apps/www/calendar/index.tsx +24 -12
  112. package/apps/www/contacts/[uid].tsx +6 -1
  113. package/apps/www/contacts/index.tsx +66 -12
  114. package/apps/www/index.tsx +91 -28
  115. package/apps/www/messages/[uid].tsx +8 -3
  116. package/apps/www/settings/auto-reply/index.tsx +13 -0
  117. package/apps/www/settings/blocked-senders/index.tsx +4 -0
  118. package/apps/www/settings/encryption/index.tsx +66 -4
  119. package/apps/www/settings/privacy/index.tsx +4 -1
  120. package/apps/www/settings/profile/index.tsx +12 -1
  121. package/apps/www/settings/sharing/index.tsx +11 -1
  122. package/apps/www/settings/signatures/[uid].tsx +6 -4
  123. package/apps/www/tasks/index.tsx +97 -29
  124. package/dist/apps/admin/audit-log/index.js +3 -3
  125. package/dist/apps/admin/branding/index.js +3 -3
  126. package/dist/apps/admin/data-requests/index.js +17 -7
  127. package/dist/apps/admin/distribution-lists/[uid].js +3 -3
  128. package/dist/apps/admin/distribution-lists/index.js +3 -3
  129. package/dist/apps/admin/distribution-lists/new/index.js +3 -3
  130. package/dist/apps/admin/domains/[uid].js +6 -5
  131. package/dist/apps/admin/domains/index.js +3 -3
  132. package/dist/apps/admin/domains/new/index.js +3 -3
  133. package/dist/apps/admin/escrow-scopes/[uid].js +11 -6
  134. package/dist/apps/admin/escrow-scopes/index.js +3 -3
  135. package/dist/apps/admin/escrow-scopes/new/index.js +9 -4
  136. package/dist/apps/admin/index.js +4 -4
  137. package/dist/apps/admin/ingest-queue/index.js +3 -3
  138. package/dist/apps/admin/mailboxes/[uid].js +15 -7
  139. package/dist/apps/admin/quarantine/index.js +4 -4
  140. package/dist/apps/admin/retention-policy/index.js +3 -3
  141. package/dist/apps/admin/signing-certificates/index.js +3 -3
  142. package/dist/apps/admin/transport-rules/[uid].js +4 -4
  143. package/dist/apps/admin/transport-rules/index.js +3 -3
  144. package/dist/apps/admin/transport-rules/new/index.js +3 -3
  145. package/dist/apps/escrow/matters/[uid].js +8 -3
  146. package/dist/apps/escrow/matters/new/index.js +4 -0
  147. package/dist/apps/shared/calendar/calendarLiveUpdates.d.ts +11 -7
  148. package/dist/apps/shared/calendar/calendarLiveUpdates.js +10 -9
  149. package/dist/apps/shared/calendar/useCalendarReminders.js +2 -0
  150. package/dist/apps/shared/components/admin/ActionAlert.d.ts +13 -0
  151. package/dist/apps/shared/components/admin/ActionAlert.js +24 -0
  152. package/dist/apps/shared/components/admin/diagnostics/InformationPanel.js +2 -2
  153. package/dist/apps/shared/components/admin/diagnostics/InstalledPlugins.js +1 -1
  154. package/dist/apps/shared/components/admin/diagnostics/LogsPanel.js +1 -1
  155. package/dist/apps/shared/components/admin/diagnostics/RuntimePanel.js +1 -1
  156. package/dist/apps/shared/components/admin/diagnostics/SystemPanel.js +1 -1
  157. package/dist/apps/shared/components/admin/diagnostics/diagnosticsApi.d.ts +2 -2
  158. package/dist/apps/shared/components/admin/distributionLists/MemberListCard.js +4 -4
  159. package/dist/apps/shared/components/admin/elevation.d.ts +9 -0
  160. package/dist/apps/shared/components/admin/elevation.js +16 -0
  161. package/dist/apps/shared/components/admin/escrowScopes/EscrowScopeKeyAndHoldersFields.d.ts +2 -0
  162. package/dist/apps/shared/components/admin/escrowScopes/EscrowScopeKeyAndHoldersFields.js +41 -1
  163. package/dist/apps/shared/components/admin/layout/AdminShell.js +2 -1
  164. package/dist/apps/shared/components/admin/mailboxes/EraseLeftoverDataDialog.js +3 -3
  165. package/dist/apps/shared/components/admin/mailboxes/EscrowScopeCard.js +4 -4
  166. package/dist/apps/shared/components/admin/mailboxes/LeftoverMailboxesSection.js +4 -4
  167. package/dist/apps/shared/components/admin/mailboxes/ResourceSettingsCard.js +3 -3
  168. package/dist/apps/shared/components/admin/mailboxes/ShareAccessCard.js +6 -6
  169. package/dist/apps/shared/components/admin/settings/BrandingForm.js +17 -7
  170. package/dist/apps/shared/components/admin/settings/DomainDnsSetup.js +4 -4
  171. package/dist/apps/shared/components/admin/settings/EncryptionPolicyForm.js +17 -5
  172. package/dist/apps/shared/components/admin/settings/LoadedSettingsForm.js +3 -3
  173. package/dist/apps/shared/components/admin/settings/MailboxCreateForm.js +8 -3
  174. package/dist/apps/shared/components/admin/settings/MailboxPolicyForm.js +3 -3
  175. package/dist/apps/shared/components/admin/settings/PluginsManager.js +103 -18
  176. package/dist/apps/shared/components/admin/settings/RetentionPolicyForm.js +17 -10
  177. package/dist/apps/shared/components/admin/setup/EscrowSetupStep.js +18 -8
  178. package/dist/apps/shared/components/admin/setup/SetupWizard.js +8 -6
  179. package/dist/apps/shared/components/admin/signOut.js +3 -0
  180. package/dist/apps/shared/components/admin/usePagedList.js +2 -2
  181. package/dist/apps/shared/components/calendar/DescriptionEditor.js +2 -1
  182. package/dist/apps/shared/components/calendar/EventDetails.d.ts +3 -1
  183. package/dist/apps/shared/components/calendar/EventDetails.js +7 -4
  184. package/dist/apps/shared/components/calendar/EventEditor.js +81 -33
  185. package/dist/apps/shared/components/calendar/EventFormParts.d.ts +3 -1
  186. package/dist/apps/shared/components/calendar/EventFormParts.js +3 -3
  187. package/dist/apps/shared/components/calendar/EventMatchNav.d.ts +1 -1
  188. package/dist/apps/shared/components/calendar/EventMatchNav.js +12 -2
  189. package/dist/apps/shared/components/calendar/EventModal.js +10 -2
  190. package/dist/apps/shared/components/calendar/FindATime.js +4 -3
  191. package/dist/apps/shared/components/calendar/ListView.d.ts +10 -4
  192. package/dist/apps/shared/components/calendar/ListView.js +92 -27
  193. package/dist/apps/shared/components/calendar/RecurrenceEditor.d.ts +4 -1
  194. package/dist/apps/shared/components/calendar/RecurrenceEditor.js +15 -10
  195. package/dist/apps/shared/components/calendar/SplitDayView.js +11 -17
  196. package/dist/apps/shared/components/calendar/TaskQuickForm.js +3 -2
  197. package/dist/apps/shared/components/calendar/TimeGridView.js +23 -21
  198. package/dist/apps/shared/components/calendar/gridLayout.d.ts +41 -0
  199. package/dist/apps/shared/components/calendar/gridLayout.js +83 -0
  200. package/dist/apps/shared/components/calendar/layout/CalendarShell.js +1 -1
  201. package/dist/apps/shared/components/calendar/timePicker.js +5 -2
  202. package/dist/apps/shared/components/contacts/ContactCard.js +9 -3
  203. package/dist/apps/shared/components/contacts/ContactDetailPane.d.ts +5 -3
  204. package/dist/apps/shared/components/contacts/ContactDetailPane.js +11 -5
  205. package/dist/apps/shared/components/contacts/ContactForm.js +54 -16
  206. package/dist/apps/shared/components/contacts/ContactPhotoEditor.d.ts +21 -0
  207. package/dist/apps/shared/components/contacts/ContactPhotoEditor.js +56 -0
  208. package/dist/apps/shared/components/contacts/ContactPhotoField.d.ts +7 -4
  209. package/dist/apps/shared/components/contacts/ContactPhotoField.js +19 -21
  210. package/dist/apps/shared/components/contacts/layout/ContactsShell.js +1 -1
  211. package/dist/apps/shared/components/contacts/participantDetails.d.ts +4 -1
  212. package/dist/apps/shared/components/contacts/participantDetails.js +17 -1
  213. package/dist/apps/shared/components/layout/AppShell.js +9 -0
  214. package/dist/apps/shared/components/layout/KeyEnrollmentGate.js +2 -3
  215. package/dist/apps/shared/components/layout/MailboxProvisioning.d.ts +4 -1
  216. package/dist/apps/shared/components/layout/MailboxProvisioning.js +24 -2
  217. package/dist/apps/shared/components/layout/RecoveryCodeUnlock.d.ts +4 -2
  218. package/dist/apps/shared/components/layout/RecoveryCodeUnlock.js +4 -2
  219. package/dist/apps/shared/components/mail/ConversationList.js +49 -6
  220. package/dist/apps/shared/components/mail/ConversationThreadPane.js +1 -1
  221. package/dist/apps/shared/components/mail/MenuButton.d.ts +2 -78
  222. package/dist/apps/shared/components/mail/MenuButton.js +2 -211
  223. package/dist/apps/shared/components/mail/MessageDetailPane.js +10 -6
  224. package/dist/apps/shared/components/mail/compose/ComposeToolbar.d.ts +3 -0
  225. package/dist/apps/shared/components/mail/compose/ComposeToolbar.js +10 -1
  226. package/dist/apps/shared/components/mail/compose/ComposeWindow.js +55 -10
  227. package/dist/apps/shared/components/mail/compose/GifPicker.js +10 -4
  228. package/dist/apps/shared/components/mail/compose/RecipientInput.js +9 -7
  229. package/dist/apps/shared/components/mail/compose/composeFlushRegistry.d.ts +7 -1
  230. package/dist/apps/shared/components/mail/compose/composeFlushRegistry.js +13 -1
  231. package/dist/apps/shared/components/mail/compose/encryptionRequirement.d.ts +5 -0
  232. package/dist/apps/shared/components/mail/compose/quotedBody.js +28 -5
  233. package/dist/apps/shared/components/mail/layout/MailShell.js +1 -1
  234. package/dist/apps/shared/components/mail/reading/MessageBody.js +11 -6
  235. package/dist/apps/shared/components/mail/reading/bodyContent.js +2 -0
  236. package/dist/apps/shared/components/mail/reading/bodyHtml.d.ts +5 -1
  237. package/dist/apps/shared/components/mail/reading/bodyHtml.js +23 -2
  238. package/dist/apps/shared/components/mail/writableMailboxes.js +2 -0
  239. package/dist/apps/shared/components/rules/RuleBuilder.js +9 -1
  240. package/dist/apps/shared/components/settings/GravatarSetting.d.ts +6 -0
  241. package/dist/apps/shared/components/settings/GravatarSetting.js +15 -0
  242. package/dist/apps/shared/components/settings/layout/SettingsShell.js +1 -1
  243. package/dist/apps/shared/components/tasks/dueDate.d.ts +12 -0
  244. package/dist/apps/shared/components/tasks/dueDate.js +26 -0
  245. package/dist/apps/shared/components/tasks/layout/TasksShell.js +1 -1
  246. package/dist/apps/shared/mail/decryptedMessages.d.ts +8 -0
  247. package/dist/apps/shared/mail/decryptedMessages.js +46 -2
  248. package/dist/apps/shared/mail/listSnapshots.js +2 -0
  249. package/dist/apps/shared/mail/outbox/sendDecision.d.ts +6 -3
  250. package/dist/apps/shared/mail/outbox/sendDecision.js +13 -3
  251. package/dist/apps/shared/mail/outbox/sendJob.d.ts +1 -0
  252. package/dist/apps/shared/mail/outbox/sendJob.js +5 -1
  253. package/dist/apps/shared/mail/useMailLiveUpdates.d.ts +3 -0
  254. package/dist/apps/shared/mail/useMailLiveUpdates.js +6 -1
  255. package/dist/apps/shared/mail/usePermanentDelete.d.ts +2 -0
  256. package/dist/apps/shared/mail/usePermanentDelete.js +1 -1
  257. package/dist/apps/shared/notifications/apiErrors.js +2 -0
  258. package/dist/apps/shared/notifications/preferences.d.ts +1 -1
  259. package/dist/apps/shared/notifications/preferences.js +1 -1
  260. package/dist/apps/shared/notifications/store.js +3 -1
  261. package/dist/apps/shared/plugins/pluginNav.d.ts +2 -1
  262. package/dist/apps/shared/plugins/pluginNav.js +4 -2
  263. package/dist/apps/www/calendar/index.js +24 -12
  264. package/dist/apps/www/contacts/[uid].js +6 -2
  265. package/dist/apps/www/contacts/index.js +62 -11
  266. package/dist/apps/www/index.js +85 -30
  267. package/dist/apps/www/messages/[uid].js +8 -3
  268. package/dist/apps/www/settings/auto-reply/index.js +13 -1
  269. package/dist/apps/www/settings/blocked-senders/index.js +4 -0
  270. package/dist/apps/www/settings/encryption/index.js +29 -5
  271. package/dist/apps/www/settings/privacy/index.js +3 -2
  272. package/dist/apps/www/settings/profile/index.js +4 -1
  273. package/dist/apps/www/settings/sharing/index.js +10 -1
  274. package/dist/apps/www/settings/signatures/[uid].js +6 -4
  275. package/dist/apps/www/tasks/index.js +94 -32
  276. package/dist/lib/admin/auditLogApi.js +2 -2
  277. package/dist/lib/admin/distributionListsApi.js +2 -2
  278. package/dist/lib/admin/domainsApi.js +2 -2
  279. package/dist/lib/admin/escrowAuditLogApi.js +2 -2
  280. package/dist/lib/admin/escrowScopesApi.js +2 -2
  281. package/dist/lib/admin/pluginsApi.d.ts +31 -2
  282. package/dist/lib/admin/pluginsApi.js +23 -1
  283. package/dist/lib/admin/retentionPolicyApi.d.ts +3 -0
  284. package/dist/lib/admin/retentionPolicyApi.js +3 -0
  285. package/dist/lib/admin/transportRulesApi.js +2 -2
  286. package/dist/lib/appearance/preferencesApi.d.ts +1 -1
  287. package/dist/lib/appearance/preferencesApi.js +3 -14
  288. package/dist/lib/auth/session.d.ts +51 -12
  289. package/dist/lib/auth/session.js +214 -38
  290. package/dist/lib/branding/brandingApi.d.ts +3 -3
  291. package/dist/lib/branding/brandingApi.js +9 -21
  292. package/dist/lib/calendar/calendarApi.js +3 -1
  293. package/dist/lib/calendar/eventSearch.js +43 -6
  294. package/dist/lib/calendar/freeBusyApi.d.ts +2 -1
  295. package/dist/lib/calendar/freeBusyApi.js +13 -5
  296. package/dist/lib/calendar/recurrence.js +51 -3
  297. package/dist/lib/calendar/useDayKey.d.ts +7 -0
  298. package/dist/lib/calendar/useDayKey.js +43 -0
  299. package/dist/lib/components/avatar/ContactAvatar.d.ts +6 -2
  300. package/dist/lib/components/avatar/ContactAvatar.js +37 -8
  301. package/dist/lib/components/avatar/ContactPhotoAvatar.d.ts +11 -0
  302. package/dist/lib/components/avatar/ContactPhotoAvatar.js +18 -0
  303. package/dist/lib/components/forms/CameraCaptureModal.d.ts +17 -0
  304. package/dist/lib/components/forms/CameraCaptureModal.js +88 -0
  305. package/dist/lib/components/forms/ImageEditBadge.d.ts +28 -0
  306. package/dist/lib/components/forms/ImageEditBadge.js +62 -0
  307. package/dist/lib/components/menus/MenuButton.d.ts +78 -0
  308. package/dist/lib/components/menus/MenuButton.js +219 -0
  309. package/dist/lib/components/navigation/BottomTabBar.d.ts +3 -1
  310. package/dist/lib/components/navigation/BottomTabBar.js +22 -3
  311. package/dist/lib/components/overlays/PopoverPortal.d.ts +2 -1
  312. package/dist/lib/components/overlays/PopoverPortal.js +3 -2
  313. package/dist/lib/components/pickers/TimeZonePicker.js +13 -1
  314. package/dist/lib/contacts/contactsApi.d.ts +5 -2
  315. package/dist/lib/contacts/contactsApi.js +16 -19
  316. package/dist/lib/contacts/gravatar.d.ts +14 -3
  317. package/dist/lib/contacts/gravatar.js +42 -5
  318. package/dist/lib/contacts/preparePhoto.d.ts +24 -0
  319. package/dist/lib/contacts/preparePhoto.js +250 -0
  320. package/dist/lib/contacts/useContactPhotoSrc.d.ts +19 -0
  321. package/dist/lib/contacts/useContactPhotoSrc.js +153 -0
  322. package/dist/lib/contacts/vcard.d.ts +3 -0
  323. package/dist/lib/contacts/vcard.js +59 -7
  324. package/dist/lib/crypto/escrowKeys.d.ts +8 -0
  325. package/dist/lib/crypto/escrowKeys.js +20 -1
  326. package/dist/lib/crypto/messageSecurity.d.ts +7 -4
  327. package/dist/lib/crypto/messageSecurity.js +23 -5
  328. package/dist/lib/crypto/passwordUnlock.d.ts +6 -1
  329. package/dist/lib/crypto/passwordUnlock.js +13 -2
  330. package/dist/lib/crypto/smime.js +12 -2
  331. package/dist/lib/mail/compose/composeQuoting.js +3 -2
  332. package/dist/lib/mail/compose/quotedImages.d.ts +6 -3
  333. package/dist/lib/mail/compose/quotedImages.js +35 -9
  334. package/dist/lib/mail/labelsApi.js +2 -2
  335. package/dist/lib/mail/mailApi.d.ts +8 -5
  336. package/dist/lib/mail/mailApi.js +73 -39
  337. package/dist/lib/mail/mailDetailHooks.js +11 -3
  338. package/dist/lib/mail/mailFilterRulesApi.js +2 -2
  339. package/dist/lib/mail/mailSignaturesApi.js +2 -2
  340. package/dist/lib/mail/mailboxImportApi.d.ts +1 -1
  341. package/dist/lib/mail/mailboxImportApi.js +3 -15
  342. package/dist/lib/mail/messageBodySanitizer.d.ts +6 -0
  343. package/dist/lib/mail/messageBodySanitizer.js +44 -1
  344. package/dist/lib/search/queryGrammar.js +12 -4
  345. package/dist/lib/search/searchTier3.d.ts +6 -1
  346. package/dist/lib/search/searchTier3.js +54 -25
  347. package/dist/lib/tasks/tasksApi.js +3 -3
  348. package/dist/lib/util/api.d.ts +26 -4
  349. package/dist/lib/util/api.js +73 -16
  350. package/dist/lib/util/apiQuery.d.ts +11 -0
  351. package/dist/lib/util/apiQuery.js +11 -0
  352. package/dist/lib/util/settleWithLimit.d.ts +5 -0
  353. package/dist/lib/util/settleWithLimit.js +25 -0
  354. package/lib/admin/auditLogApi.ts +2 -2
  355. package/lib/admin/distributionListsApi.ts +2 -2
  356. package/lib/admin/domainsApi.ts +2 -2
  357. package/lib/admin/escrowAuditLogApi.ts +2 -2
  358. package/lib/admin/escrowScopesApi.ts +2 -2
  359. package/lib/admin/pluginsApi.ts +45 -3
  360. package/lib/admin/retentionPolicyApi.ts +4 -0
  361. package/lib/admin/transportRulesApi.ts +2 -2
  362. package/lib/appearance/preferencesApi.ts +3 -14
  363. package/lib/auth/session.ts +239 -39
  364. package/lib/branding/brandingApi.ts +9 -21
  365. package/lib/calendar/calendarApi.ts +3 -1
  366. package/lib/calendar/eventSearch.ts +46 -6
  367. package/lib/calendar/freeBusyApi.ts +14 -6
  368. package/lib/calendar/recurrence.ts +59 -8
  369. package/lib/calendar/useDayKey.ts +45 -0
  370. package/lib/components/avatar/ContactAvatar.tsx +46 -8
  371. package/lib/components/avatar/ContactPhotoAvatar.tsx +26 -0
  372. package/lib/components/forms/CameraCaptureModal.tsx +133 -0
  373. package/lib/components/forms/ImageEditBadge.tsx +121 -0
  374. package/lib/components/menus/MenuButton.tsx +408 -0
  375. package/lib/components/navigation/BottomTabBar.tsx +30 -8
  376. package/lib/components/overlays/PopoverPortal.tsx +3 -2
  377. package/lib/components/pickers/TimeZonePicker.tsx +17 -1
  378. package/lib/contacts/contactsApi.ts +18 -19
  379. package/lib/contacts/gravatar.ts +47 -5
  380. package/lib/contacts/preparePhoto.ts +273 -0
  381. package/lib/contacts/useContactPhotoSrc.ts +177 -0
  382. package/lib/contacts/vcard.ts +60 -7
  383. package/lib/crypto/escrowKeys.ts +21 -1
  384. package/lib/crypto/messageSecurity.ts +33 -9
  385. package/lib/crypto/passwordUnlock.ts +14 -2
  386. package/lib/crypto/smime.ts +13 -2
  387. package/lib/mail/compose/composeQuoting.ts +3 -2
  388. package/lib/mail/compose/quotedImages.ts +39 -9
  389. package/lib/mail/labelsApi.ts +2 -2
  390. package/lib/mail/mailApi.ts +96 -39
  391. package/lib/mail/mailDetailHooks.ts +11 -3
  392. package/lib/mail/mailFilterRulesApi.ts +2 -2
  393. package/lib/mail/mailSignaturesApi.ts +2 -2
  394. package/lib/mail/mailboxImportApi.ts +9 -15
  395. package/lib/mail/messageBodySanitizer.ts +47 -1
  396. package/lib/search/queryGrammar.ts +13 -4
  397. package/lib/search/searchTier3.ts +65 -32
  398. package/lib/tasks/tasksApi.ts +3 -3
  399. package/lib/util/api.ts +99 -16
  400. package/lib/util/apiQuery.ts +13 -0
  401. package/lib/util/settleWithLimit.ts +25 -0
  402. package/package.json +1 -1
@@ -4,14 +4,14 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
4
4
  // SPDX-License-Identifier: MPL-2.0
5
5
  ///////////////////////////////////////////////////////////////////////////////
6
6
  import { useEffect, useRef, useState } from "react";
7
- import { ApiRequestError } from "../../../lib/util/api.js";
7
+ import { actionErrorMessage } from "../../shared/components/admin/elevation.js";
8
8
  import { createExportRequest, exportRequestDownloadUrl, listExportRequests, } from "../../../lib/mail/dataExportApi.js";
9
9
  import { listImportRequests, uploadMailboxImport, } from "../../../lib/mail/mailboxImportApi.js";
10
10
  import { approveErasureRequest, denyErasureRequest, listErasureRequests, } from "../../../lib/mail/erasureRequestApi.js";
11
11
  import { listFolders } from "../../../lib/mail/mailApi.js";
12
12
  import AdminShell from "../../shared/components/admin/layout/AdminShell.js";
13
13
  import { LoadMoreButton, usePagedList } from "../../shared/components/admin/usePagedList.js";
14
- import Alert from "../../../lib/components/feedback/Alert.js";
14
+ import Alert from "../../shared/components/admin/ActionAlert.js";
15
15
  import Button from "../../../lib/components/buttons/Button.js";
16
16
  import Modal from "../../../lib/components/overlays/Modal.js";
17
17
  const INPUT_CLASS = "text-sm border border-border rounded-sm py-1.5 px-2 bg-surface";
@@ -57,7 +57,7 @@ function ExportRequestsSection() {
57
57
  await list.reload();
58
58
  }
59
59
  catch (err) {
60
- setCreateError(err instanceof ApiRequestError ? err.message : "Could not start this export.");
60
+ setCreateError(actionErrorMessage(err, "Could not start this export."));
61
61
  }
62
62
  finally {
63
63
  setCreating(false);
@@ -79,7 +79,10 @@ function ImportRequestsSection() {
79
79
  useEffect(() => {
80
80
  void list.reload();
81
81
  }, []);
82
+ // Only the latest lookup's answer is applied: a slower answer for a mailbox typed earlier would otherwise list its folders beside the mailbox now named.
83
+ const folderLookup = useRef(0);
82
84
  function handleLoadFolders() {
85
+ const lookup = ++folderLookup.current;
83
86
  const uid = mailboxUid.trim();
84
87
  setTargetFolderUid("");
85
88
  setFolders([]);
@@ -89,11 +92,18 @@ function ImportRequestsSection() {
89
92
  }
90
93
  listFolders(uid)
91
94
  .then((all) => {
95
+ if (lookup !== folderLookup.current) {
96
+ return;
97
+ }
92
98
  const mailFolders = all.filter((f) => !NON_MAIL_FOLDER_TYPES.has(f.type));
93
99
  setFolders(mailFolders);
94
100
  setTargetFolderUid(mailFolders[0]?.uid ?? "");
95
101
  })
96
- .catch((err) => setFolderError(err instanceof ApiRequestError ? err.message : "Could not load this mailbox's folders."));
102
+ .catch((err) => {
103
+ if (lookup === folderLookup.current) {
104
+ setFolderError(actionErrorMessage(err, "Could not load this mailbox's folders."));
105
+ }
106
+ });
97
107
  }
98
108
  function handleFileChange(e) {
99
109
  const file = e.target.files?.[0];
@@ -105,7 +115,7 @@ function ImportRequestsSection() {
105
115
  setUploading(true);
106
116
  uploadMailboxImport(file, { format: importFormatFromFilename(file.name), targetFolderUid, mailboxUid: mailboxUid.trim() })
107
117
  .then(() => list.reload())
108
- .catch((err) => setUploadError(err instanceof ApiRequestError ? err.message : "Could not upload this file."))
118
+ .catch((err) => setUploadError(actionErrorMessage(err, "Could not upload this file.")))
109
119
  .finally(() => setUploading(false));
110
120
  }
111
121
  return (_jsxs("section", { children: [_jsx("h2", { className: "text-sm font-bold uppercase tracking-wide text-text-muted mb-3", children: "Import requests" }), _jsxs("div", { className: "flex items-end gap-3 mb-2 flex-wrap", children: [_jsxs("label", { className: "flex flex-col gap-1.5 text-sm", children: [_jsx("span", { className: "font-semibold", children: "Mailbox UID" }), _jsx("input", { "aria-label": "Import mailbox UID", className: INPUT_CLASS, value: mailboxUid, onChange: (e) => setMailboxUid(e.target.value), onBlur: handleLoadFolders })] }), folders.length > 0 && (_jsxs("label", { className: "flex flex-col gap-1.5 text-sm", children: [_jsx("span", { className: "font-semibold", children: "Destination folder" }), _jsx("select", { "aria-label": "Import destination folder", className: INPUT_CLASS, value: targetFolderUid, onChange: (e) => setTargetFolderUid(e.target.value), children: folders.map((folder) => (_jsx("option", { value: folder.uid, children: folder.name }, folder.uid))) })] })), _jsx(Button, { type: "button", variant: "secondary", className: "!w-auto", loading: uploading, disabled: uploading || !targetFolderUid, onClick: () => fileInputRef.current?.click(), children: "Upload Mbox or PST file" }), _jsx("input", { ref: fileInputRef, type: "file", accept: ".mbox,.pst", "aria-label": "Upload mail archive", className: "hidden", onChange: handleFileChange })] }), folderError && _jsx(Alert, { children: folderError }), uploadError && _jsx(Alert, { children: uploadError }), list.loadError && _jsx(Alert, { children: list.loadError }), list.loading ? (_jsx("p", { className: "text-sm text-text-muted", children: "Loading\u2026" })) : list.items.length === 0 ? (_jsx("p", { className: "text-sm text-text-muted", children: "No import requests." })) : (_jsx("ul", { className: "flex flex-col gap-2", children: list.items.map((request) => (_jsxs("li", { className: "flex items-center justify-between gap-3 text-sm py-1.5 px-3 bg-surface-alt rounded-sm", children: [_jsxs("span", { children: [request.mailboxUid, " \u00B7 ", request.format.toUpperCase(), " \u00B7", " ", new Date(request.dateCreated).toLocaleString(), request.status === "completed" && (_jsxs("span", { className: "text-text-muted", children: [" ", "\u2014 ", request.importedCount ?? 0, " imported", request.failedCount ? `, ${request.failedCount} failed` : ""] })), request.status === "failed" && request.errorMessage && (_jsxs("span", { className: "text-danger", children: [" \u2014 ", request.errorMessage] }))] }), _jsx("span", { className: `text-xs font-bold uppercase tracking-wide py-0.5 px-2 rounded-pill ${statusBadgeClass(request.status)}`, children: statusLabel(request.status) })] }, request.uid))) })), _jsx(LoadMoreButton, { list: list, label: "Load more import requests" })] }));
@@ -142,7 +152,7 @@ function ErasureRequestsSection() {
142
152
  await list.reload();
143
153
  }
144
154
  catch (err) {
145
- setApproveError(err instanceof ApiRequestError ? err.message : "Could not approve this request.");
155
+ setApproveError(actionErrorMessage(err, "Could not approve this request."));
146
156
  }
147
157
  finally {
148
158
  setApproving(false);
@@ -167,7 +177,7 @@ function ErasureRequestsSection() {
167
177
  await list.reload();
168
178
  }
169
179
  catch (err) {
170
- setDenyError(err instanceof ApiRequestError ? err.message : "Could not deny this request.");
180
+ setDenyError(actionErrorMessage(err, "Could not deny this request."));
171
181
  }
172
182
  finally {
173
183
  setDenying(false);
@@ -4,11 +4,11 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
4
4
  // SPDX-License-Identifier: MPL-2.0
5
5
  ///////////////////////////////////////////////////////////////////////////////
6
6
  import { useEffect, useState } from "react";
7
- import { ApiRequestError } from "../../../lib/util/api.js";
8
7
  import { getDistributionList } from "../../../lib/admin/distributionListsApi.js";
9
8
  import AdminShell from "../../shared/components/admin/layout/AdminShell.js";
10
9
  import MemberListCard from "../../shared/components/admin/distributionLists/MemberListCard.js";
11
- import Alert from "../../../lib/components/feedback/Alert.js";
10
+ import Alert from "../../shared/components/admin/ActionAlert.js";
11
+ import { actionErrorMessage } from "../../shared/components/admin/elevation.js";
12
12
  export default function DistributionListDetailPage(props) {
13
13
  return (_jsx(AdminShell, { ...props, active: "distributionLists", children: _jsx(DistributionListDetailContent, { uid: props.params.uid }) }));
14
14
  }
@@ -21,7 +21,7 @@ function DistributionListDetailContent({ uid }) {
21
21
  setError(null);
22
22
  getDistributionList(uid)
23
23
  .then(setList)
24
- .catch((err) => setError(err instanceof ApiRequestError ? err.message : "Could not load this distribution list."))
24
+ .catch((err) => setError(actionErrorMessage(err, "Could not load this distribution list.")))
25
25
  .finally(() => setLoading(false));
26
26
  }, [uid]);
27
27
  if (loading) {
@@ -4,11 +4,11 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
4
4
  // SPDX-License-Identifier: MPL-2.0
5
5
  ///////////////////////////////////////////////////////////////////////////////
6
6
  import { useEffect, useState } from "react";
7
- import { ApiRequestError } from "../../../lib/util/api.js";
8
7
  import { listDistributionLists } from "../../../lib/admin/distributionListsApi.js";
9
8
  import AdminShell from "../../shared/components/admin/layout/AdminShell.js";
10
- import Alert from "../../../lib/components/feedback/Alert.js";
9
+ import Alert from "../../shared/components/admin/ActionAlert.js";
11
10
  import Button from "../../../lib/components/buttons/Button.js";
11
+ import { actionErrorMessage } from "../../shared/components/admin/elevation.js";
12
12
  const PAGE_SIZE = 25;
13
13
  export default function DistributionListsPage(props) {
14
14
  return (_jsx(AdminShell, { ...props, active: "distributionLists", children: _jsx(DistributionListsContent, {}) }));
@@ -23,7 +23,7 @@ function DistributionListsContent() {
23
23
  setError(null);
24
24
  listDistributionLists({ page, limit: PAGE_SIZE })
25
25
  .then(setLists)
26
- .catch((err) => setError(err instanceof ApiRequestError ? err.message : "Could not load distribution lists."))
26
+ .catch((err) => setError(actionErrorMessage(err, "Could not load distribution lists.")))
27
27
  .finally(() => setLoading(false));
28
28
  }, [page]);
29
29
  const hasNextPage = lists.length === PAGE_SIZE;
@@ -5,12 +5,12 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
5
5
  ///////////////////////////////////////////////////////////////////////////////
6
6
  import { useState } from "react";
7
7
  import { useRouter } from "@rapidrest/react/client";
8
- import { ApiRequestError } from "../../../../lib/util/api.js";
9
8
  import { createDistributionList } from "../../../../lib/admin/distributionListsApi.js";
10
9
  import AdminShell from "../../../shared/components/admin/layout/AdminShell.js";
11
- import Alert from "../../../../lib/components/feedback/Alert.js";
10
+ import Alert from "../../../shared/components/admin/ActionAlert.js";
12
11
  import Button from "../../../../lib/components/buttons/Button.js";
13
12
  import FormField from "../../../../lib/components/forms/FormField.js";
13
+ import { actionErrorMessage } from "../../../shared/components/admin/elevation.js";
14
14
  const INPUT_CLASS = "w-full text-sm py-2.5 px-3 border border-border rounded-sm bg-surface text-text focus:outline-none focus:border-primary";
15
15
  export default function NewDistributionListPage(props) {
16
16
  return (_jsx(AdminShell, { ...props, active: "distributionLists", children: _jsx(NewDistributionListForm, {}) }));
@@ -43,7 +43,7 @@ function NewDistributionListForm() {
43
43
  void navigate(`/admin/distribution-lists/${encodeURIComponent(list.uid)}`);
44
44
  }
45
45
  catch (err) {
46
- setError(err instanceof ApiRequestError ? err.message : "Could not create the distribution list.");
46
+ setError(actionErrorMessage(err, "Could not create the distribution list."));
47
47
  }
48
48
  finally {
49
49
  setSaving(false);
@@ -5,14 +5,14 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
5
5
  ///////////////////////////////////////////////////////////////////////////////
6
6
  import { useState } from "react";
7
7
  import { useRouter } from "@rapidrest/react/client";
8
- import { ApiRequestError } from "../../../lib/util/api.js";
9
8
  import { deleteDomain, updateDomain } from "../../../lib/admin/domainsApi.js";
10
9
  import AdminShell from "../../shared/components/admin/layout/AdminShell.js";
11
10
  import DomainDnsSetup from "../../shared/components/admin/settings/DomainDnsSetup.js";
12
- import Alert from "../../../lib/components/feedback/Alert.js";
11
+ import Alert from "../../shared/components/admin/ActionAlert.js";
13
12
  import Button from "../../../lib/components/buttons/Button.js";
14
13
  import FormField from "../../../lib/components/forms/FormField.js";
15
14
  import Modal from "../../../lib/components/overlays/Modal.js";
15
+ import { actionErrorMessage } from "../../shared/components/admin/elevation.js";
16
16
  const INPUT_CLASS = "w-full text-sm py-2.5 px-3 border border-border rounded-sm bg-surface text-text focus:outline-none focus:border-primary";
17
17
  export default function DomainDetailPage(props) {
18
18
  return (_jsx(AdminShell, { ...props, active: "domains", children: _jsx(DomainDetailContent, { uid: props.params.uid }) }));
@@ -44,7 +44,7 @@ function DomainDetailContent({ uid }) {
44
44
  void navigate("/admin/domains");
45
45
  }
46
46
  catch (err) {
47
- setDeleteError(err instanceof ApiRequestError ? err.message : "Could not delete this domain.");
47
+ setDeleteError(actionErrorMessage(err, "Could not delete this domain."));
48
48
  setDeleting(false);
49
49
  }
50
50
  }
@@ -52,19 +52,20 @@ function DomainDetailContent({ uid }) {
52
52
  setDomain(d);
53
53
  setAliasInput((current) => (current === null ? d?.aliasOf ?? "" : current));
54
54
  }
55
+ // A blank input is sent as "" (the server's way to clear an alias): an absent key (what `undefined` becomes in JSON) leaves the stored alias alone.
55
56
  async function handleSaveAlias() {
56
57
  setSavingAlias(true);
57
58
  setAliasError(null);
58
59
  setAliasSaved(false);
59
60
  try {
60
- const updated = await updateDomain({ uid: domain.uid, version: domain.version, aliasOf: aliasInput.trim() || undefined });
61
+ const updated = await updateDomain({ uid: domain.uid, version: domain.version, aliasOf: aliasInput.trim() });
61
62
  setDomain(updated);
62
63
  setAliasInput(updated.aliasOf ?? "");
63
64
  setAliasSaved(true);
64
65
  setRefreshCount((c) => c + 1);
65
66
  }
66
67
  catch (err) {
67
- setAliasError(err instanceof ApiRequestError ? err.message : "Could not update this domain.");
68
+ setAliasError(actionErrorMessage(err, "Could not update this domain."));
68
69
  }
69
70
  finally {
70
71
  setSavingAlias(false);
@@ -4,11 +4,11 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
4
4
  // SPDX-License-Identifier: MPL-2.0
5
5
  ///////////////////////////////////////////////////////////////////////////////
6
6
  import { useEffect, useState } from "react";
7
- import { ApiRequestError } from "../../../lib/util/api.js";
8
7
  import { listDomains } from "../../../lib/admin/domainsApi.js";
9
8
  import AdminShell from "../../shared/components/admin/layout/AdminShell.js";
10
- import Alert from "../../../lib/components/feedback/Alert.js";
9
+ import Alert from "../../shared/components/admin/ActionAlert.js";
11
10
  import Button from "../../../lib/components/buttons/Button.js";
11
+ import { actionErrorMessage } from "../../shared/components/admin/elevation.js";
12
12
  const PAGE_SIZE = 25;
13
13
  export default function DomainsListPage(props) {
14
14
  return (_jsx(AdminShell, { ...props, active: "domains", children: _jsx(DomainsListContent, {}) }));
@@ -23,7 +23,7 @@ function DomainsListContent() {
23
23
  setError(null);
24
24
  listDomains({ page, limit: PAGE_SIZE })
25
25
  .then(setDomains)
26
- .catch((err) => setError(err instanceof ApiRequestError ? err.message : "Could not load domains."))
26
+ .catch((err) => setError(actionErrorMessage(err, "Could not load domains.")))
27
27
  .finally(() => setLoading(false));
28
28
  }, [page]);
29
29
  const hasNextPage = domains.length === PAGE_SIZE;
@@ -5,12 +5,12 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
5
5
  ///////////////////////////////////////////////////////////////////////////////
6
6
  import { useEffect, useState } from "react";
7
7
  import { useRouter } from "@rapidrest/react/client";
8
- import { ApiRequestError } from "../../../../lib/util/api.js";
9
8
  import { createDomain, listDomains } from "../../../../lib/admin/domainsApi.js";
10
9
  import AdminShell from "../../../shared/components/admin/layout/AdminShell.js";
11
- import Alert from "../../../../lib/components/feedback/Alert.js";
10
+ import Alert from "../../../shared/components/admin/ActionAlert.js";
12
11
  import Button from "../../../../lib/components/buttons/Button.js";
13
12
  import FormField from "../../../../lib/components/forms/FormField.js";
13
+ import { actionErrorMessage } from "../../../shared/components/admin/elevation.js";
14
14
  const INPUT_CLASS = "w-full text-sm py-2.5 px-3 border border-border rounded-sm bg-surface text-text focus:outline-none focus:border-primary";
15
15
  export default function NewDomainPage(props) {
16
16
  return (_jsx(AdminShell, { ...props, active: "domains", children: _jsx(NewDomainForm, {}) }));
@@ -42,7 +42,7 @@ function NewDomainForm() {
42
42
  void navigate(`/admin/domains/${encodeURIComponent(domain.uid)}`);
43
43
  }
44
44
  catch (err) {
45
- setError(err instanceof ApiRequestError ? err.message : "Could not create the domain.");
45
+ setError(actionErrorMessage(err, "Could not create the domain."));
46
46
  }
47
47
  finally {
48
48
  setSaving(false);
@@ -5,15 +5,15 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
5
5
  ///////////////////////////////////////////////////////////////////////////////
6
6
  import { useEffect, useState } from "react";
7
7
  import { useRouter } from "@rapidrest/react/client";
8
- import { ApiRequestError } from "../../../lib/util/api.js";
9
8
  import { toDatetimeLocal } from "../../../lib/util/dateInput.js";
10
9
  import { deleteEscrowScope, getEscrowScope, updateEscrowScope, } from "../../../lib/admin/escrowScopesApi.js";
11
10
  import AdminShell from "../../shared/components/admin/layout/AdminShell.js";
12
- import EscrowScopeKeyAndHoldersFields, { selfAsHolderError, } from "../../shared/components/admin/escrowScopes/EscrowScopeKeyAndHoldersFields.js";
13
- import Alert from "../../../lib/components/feedback/Alert.js";
11
+ import EscrowScopeKeyAndHoldersFields, { keyValidityError, selfAsHolderError, } from "../../shared/components/admin/escrowScopes/EscrowScopeKeyAndHoldersFields.js";
12
+ import Alert from "../../shared/components/admin/ActionAlert.js";
14
13
  import Button from "../../../lib/components/buttons/Button.js";
15
14
  import FormField from "../../../lib/components/forms/FormField.js";
16
15
  import Modal from "../../../lib/components/overlays/Modal.js";
16
+ import { actionErrorMessage } from "../../shared/components/admin/elevation.js";
17
17
  const INPUT_CLASS = "w-full text-sm py-2.5 px-3 border border-border rounded-sm bg-surface text-text focus:outline-none focus:border-primary";
18
18
  function toFieldsValue(scope) {
19
19
  return {
@@ -121,7 +121,7 @@ function EscrowScopeDetailContent({ uid, adminUid }) {
121
121
  setFields(toFieldsValue(loaded));
122
122
  }
123
123
  })
124
- .catch((err) => setError(err instanceof ApiRequestError ? err.message : "Could not load this escrow scope."))
124
+ .catch((err) => setError(actionErrorMessage(err, "Could not load this escrow scope.")))
125
125
  .finally(() => setLoading(false));
126
126
  }, [uid]);
127
127
  // Only ever invoked from the form below, which itself only renders once `original`/`fields` are
@@ -139,6 +139,11 @@ function EscrowScopeDetailContent({ uid, adminUid }) {
139
139
  setError("The public key, its type, and its fingerprint are all required.");
140
140
  return;
141
141
  }
142
+ const validityError = keyValidityError(fields);
143
+ if (validityError) {
144
+ setError(validityError);
145
+ return;
146
+ }
142
147
  if (fields.holderUserUids.length === 0) {
143
148
  setError("At least one holder is required.");
144
149
  return;
@@ -181,7 +186,7 @@ function EscrowScopeDetailContent({ uid, adminUid }) {
181
186
  setSaved(true);
182
187
  }
183
188
  catch (err) {
184
- setError(err instanceof ApiRequestError ? err.message : "Could not save this escrow scope.");
189
+ setError(actionErrorMessage(err, "Could not save this escrow scope."));
185
190
  }
186
191
  finally {
187
192
  setSaving(false);
@@ -205,7 +210,7 @@ function EscrowScopeDetailContent({ uid, adminUid }) {
205
210
  catch (err) {
206
211
  // Most commonly a 409 ("referenced by an existing Matter") — see `deleteEscrowScope()`'s own
207
212
  // doc comment - surfaced as-is rather than special-cased.
208
- setDeleteError(err instanceof ApiRequestError ? err.message : "Could not delete this escrow scope.");
213
+ setDeleteError(actionErrorMessage(err, "Could not delete this escrow scope."));
209
214
  setDeleting(false);
210
215
  }
211
216
  }
@@ -4,11 +4,11 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
4
4
  // SPDX-License-Identifier: MPL-2.0
5
5
  ///////////////////////////////////////////////////////////////////////////////
6
6
  import { useEffect, useState } from "react";
7
- import { ApiRequestError } from "../../../lib/util/api.js";
8
7
  import { listEscrowScopes } from "../../../lib/admin/escrowScopesApi.js";
9
8
  import AdminShell from "../../shared/components/admin/layout/AdminShell.js";
10
- import Alert from "../../../lib/components/feedback/Alert.js";
9
+ import Alert from "../../shared/components/admin/ActionAlert.js";
11
10
  import Button from "../../../lib/components/buttons/Button.js";
11
+ import { actionErrorMessage } from "../../shared/components/admin/elevation.js";
12
12
  const PAGE_SIZE = 25;
13
13
  export default function EscrowScopesPage(props) {
14
14
  return (_jsx(AdminShell, { ...props, active: "escrowScopes", children: _jsx(EscrowScopesContent, {}) }));
@@ -23,7 +23,7 @@ function EscrowScopesContent() {
23
23
  setError(null);
24
24
  listEscrowScopes({ page, limit: PAGE_SIZE })
25
25
  .then(setScopes)
26
- .catch((err) => setError(err instanceof ApiRequestError ? err.message : "Could not load escrow scopes."))
26
+ .catch((err) => setError(actionErrorMessage(err, "Could not load escrow scopes.")))
27
27
  .finally(() => setLoading(false));
28
28
  }, [page]);
29
29
  const hasNextPage = scopes.length === PAGE_SIZE;
@@ -5,13 +5,13 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
5
5
  ///////////////////////////////////////////////////////////////////////////////
6
6
  import { useState } from "react";
7
7
  import { useRouter } from "@rapidrest/react/client";
8
- import { ApiRequestError } from "../../../../lib/util/api.js";
9
8
  import { createEscrowScope } from "../../../../lib/admin/escrowScopesApi.js";
10
9
  import AdminShell from "../../../shared/components/admin/layout/AdminShell.js";
11
- import EscrowScopeKeyAndHoldersFields, { emptyEscrowScopeKeyAndHoldersValue, selfAsHolderError, } from "../../../shared/components/admin/escrowScopes/EscrowScopeKeyAndHoldersFields.js";
12
- import Alert from "../../../../lib/components/feedback/Alert.js";
10
+ import EscrowScopeKeyAndHoldersFields, { emptyEscrowScopeKeyAndHoldersValue, keyValidityError, selfAsHolderError, } from "../../../shared/components/admin/escrowScopes/EscrowScopeKeyAndHoldersFields.js";
11
+ import Alert from "../../../shared/components/admin/ActionAlert.js";
13
12
  import Button from "../../../../lib/components/buttons/Button.js";
14
13
  import FormField from "../../../../lib/components/forms/FormField.js";
14
+ import { actionErrorMessage } from "../../../shared/components/admin/elevation.js";
15
15
  const INPUT_CLASS = "w-full text-sm py-2.5 px-3 border border-border rounded-sm bg-surface text-text focus:outline-none focus:border-primary";
16
16
  export default function NewEscrowScopePage(props) {
17
17
  return (_jsx(AdminShell, { ...props, active: "escrowScopes", children: _jsx(NewEscrowScopeForm, { adminUid: props.userUid }) }));
@@ -34,6 +34,11 @@ function NewEscrowScopeForm({ adminUid }) {
34
34
  setError("The public key, its type, and its fingerprint are all required.");
35
35
  return;
36
36
  }
37
+ const validityError = keyValidityError(keyAndHolders);
38
+ if (validityError) {
39
+ setError(validityError);
40
+ return;
41
+ }
37
42
  if (keyAndHolders.holderUserUids.length === 0) {
38
43
  setError("At least one holder is required.");
39
44
  return;
@@ -66,7 +71,7 @@ function NewEscrowScopeForm({ adminUid }) {
66
71
  void navigate(`/admin/escrow-scopes/${encodeURIComponent(created.uid)}`);
67
72
  }
68
73
  catch (err) {
69
- setError(err instanceof ApiRequestError ? err.message : "Could not create the escrow scope.");
74
+ setError(actionErrorMessage(err, "Could not create the escrow scope."));
70
75
  }
71
76
  finally {
72
77
  setSaving(false);
@@ -5,15 +5,15 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
5
5
  ///////////////////////////////////////////////////////////////////////////////
6
6
  import { useEffect, useState } from "react";
7
7
  import { useRouter } from "@rapidrest/react/client";
8
- import { ApiRequestError } from "../../lib/util/api.js";
9
8
  import { listMailboxes } from "../../lib/mail/mailApi.js";
10
9
  import { reopenSetup } from "../../lib/admin/setupApi.js";
11
10
  import AdminShell from "../shared/components/admin/layout/AdminShell.js";
12
11
  import LeftoverMailboxesSection from "../shared/components/admin/mailboxes/LeftoverMailboxesSection.js";
13
12
  import MailboxTable from "../shared/components/admin/mailboxes/MailboxTable.js";
14
- import Alert from "../../lib/components/feedback/Alert.js";
13
+ import Alert from "../shared/components/admin/ActionAlert.js";
15
14
  import Button from "../../lib/components/buttons/Button.js";
16
15
  import Modal from "../../lib/components/overlays/Modal.js";
16
+ import { actionErrorMessage } from "../shared/components/admin/elevation.js";
17
17
  const PAGE_SIZE = 25;
18
18
  export default function MailboxesListPage(props) {
19
19
  return (_jsx(AdminShell, { ...props, active: "mailboxes", children: _jsx(MailboxesListContent, {}) }));
@@ -30,7 +30,7 @@ function MailboxesListContent() {
30
30
  // The administration scope: every mailbox as administrative metadata - the console never shows anybody's mail.
31
31
  listMailboxes({ page, limit: PAGE_SIZE, scope: "admin" })
32
32
  .then(setMailboxes)
33
- .catch((err) => setError(err instanceof ApiRequestError ? err.message : "Could not load mailboxes."))
33
+ .catch((err) => setError(actionErrorMessage(err, "Could not load mailboxes.")))
34
34
  .finally(() => setLoading(false));
35
35
  }, [page]);
36
36
  const hasNextPage = mailboxes.length === PAGE_SIZE;
@@ -43,7 +43,7 @@ function MailboxesListContent() {
43
43
  void navigate("/admin/setup");
44
44
  }
45
45
  catch (err) {
46
- setError(err instanceof ApiRequestError ? err.message : "Could not reopen setup.");
46
+ setError(actionErrorMessage(err, "Could not reopen setup."));
47
47
  setReopening(false);
48
48
  setConfirmingSetup(false);
49
49
  }
@@ -4,11 +4,11 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
4
4
  // SPDX-License-Identifier: MPL-2.0
5
5
  ///////////////////////////////////////////////////////////////////////////////
6
6
  import { useEffect, useState } from "react";
7
- import { ApiRequestError } from "../../../lib/util/api.js";
8
7
  import { listIngestQueue } from "../../../lib/mail/mailApi.js";
9
8
  import AdminShell from "../../shared/components/admin/layout/AdminShell.js";
10
- import Alert from "../../../lib/components/feedback/Alert.js";
9
+ import Alert from "../../shared/components/admin/ActionAlert.js";
11
10
  import Button from "../../../lib/components/buttons/Button.js";
11
+ import { actionErrorMessage } from "../../shared/components/admin/elevation.js";
12
12
  const PAGE_SIZE = 25;
13
13
  export function readMailboxUid() {
14
14
  if (typeof window === "undefined")
@@ -49,7 +49,7 @@ function IngestQueueContent() {
49
49
  })
50
50
  .catch((err) => {
51
51
  if (!cancelled)
52
- setError(err instanceof ApiRequestError ? err.message : "Could not load the ingest queue.");
52
+ setError(actionErrorMessage(err, "Could not load the ingest queue."));
53
53
  })
54
54
  .finally(() => {
55
55
  if (!cancelled)
@@ -5,13 +5,14 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
5
5
  ///////////////////////////////////////////////////////////////////////////////
6
6
  import { useEffect, useState } from "react";
7
7
  import { useRouter } from "@rapidrest/react/client";
8
- import { ApiRequestError } from "../../../lib/util/api.js";
9
8
  import { deleteMailbox, getMailbox, impersonateUser } from "../../../lib/mail/mailApi.js";
10
9
  import AdminShell from "../../shared/components/admin/layout/AdminShell.js";
10
+ import { actionErrorMessage } from "../../shared/components/admin/elevation.js";
11
+ import { resetNotifications } from "../../shared/notifications/store.js";
11
12
  import ShareAccessCard from "../../shared/components/admin/mailboxes/ShareAccessCard.js";
12
13
  import ResourceSettingsCard from "../../shared/components/admin/mailboxes/ResourceSettingsCard.js";
13
14
  import EscrowScopeCard from "../../shared/components/admin/mailboxes/EscrowScopeCard.js";
14
- import Alert from "../../../lib/components/feedback/Alert.js";
15
+ import Alert from "../../shared/components/admin/ActionAlert.js";
15
16
  import Button from "../../../lib/components/buttons/Button.js";
16
17
  import { describeTimeZone } from "../../../lib/util/timeZone.js";
17
18
  import Modal from "../../../lib/components/overlays/Modal.js";
@@ -56,10 +57,12 @@ function MailboxDetailContent({ uid, impersonationBaseUrl, currentUserUid, }) {
56
57
  setAccessError(null);
57
58
  try {
58
59
  await impersonateUser(impersonationBaseUrl ?? "", mailbox.ownerUserUid);
60
+ // The administrator's own notification history is not the impersonated user's to read.
61
+ resetNotifications();
59
62
  window.location.href = "/";
60
63
  }
61
64
  catch (err) {
62
- setAccessError(err instanceof ApiRequestError ? err.message : "Could not impersonate this user.");
65
+ setAccessError(actionErrorMessage(err, "Could not impersonate this user."));
63
66
  setImpersonating(false);
64
67
  }
65
68
  }
@@ -85,18 +88,23 @@ function MailboxDetailContent({ uid, impersonationBaseUrl, currentUserUid, }) {
85
88
  // Most commonly a 409 if this mailbox is a custodian on an open legal hold (restapi's own
86
89
  // `assertNotOnLegalHold()`, naming the blocking Matter uid(s)) - surfaced as-is, same as
87
90
  // every other destructive-action error in this codebase, rather than special-cased here.
88
- setDeleteError(err instanceof ApiRequestError ? err.message : "Could not delete this mailbox.");
91
+ setDeleteError(actionErrorMessage(err, "Could not delete this mailbox."));
89
92
  setDeleting(false);
90
93
  }
91
94
  }
92
95
  useEffect(() => {
96
+ // An answer for a mailbox since replaced (another uid) must not be shown as the current one: the delete and impersonate actions act on what is shown.
97
+ let cancelled = false;
93
98
  setLoading(true);
94
99
  setError(null);
95
100
  // The administration scope: administrative metadata only - the console never shows a mailbox's mail or settings.
96
101
  getMailbox(uid, { scope: "admin" })
97
- .then(setMailbox)
98
- .catch((err) => setError(err instanceof ApiRequestError ? err.message : "Could not load this mailbox."))
99
- .finally(() => setLoading(false));
102
+ .then((loaded) => !cancelled && setMailbox(loaded))
103
+ .catch((err) => !cancelled && setError(actionErrorMessage(err, "Could not load this mailbox.")))
104
+ .finally(() => !cancelled && setLoading(false));
105
+ return () => {
106
+ cancelled = true;
107
+ };
100
108
  }, [uid]);
101
109
  if (loading) {
102
110
  return _jsx("p", { className: "text-sm text-text-muted", children: "Loading\u2026" });
@@ -4,12 +4,12 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
4
4
  // SPDX-License-Identifier: MPL-2.0
5
5
  ///////////////////////////////////////////////////////////////////////////////
6
6
  import { useEffect, useState } from "react";
7
- import { ApiRequestError } from "../../../lib/util/api.js";
8
7
  import { listQuarantine, releaseQuarantineEntry } from "../../../lib/mail/mailApi.js";
9
8
  import AdminShell from "../../shared/components/admin/layout/AdminShell.js";
10
- import Alert from "../../../lib/components/feedback/Alert.js";
9
+ import Alert from "../../shared/components/admin/ActionAlert.js";
11
10
  import Button from "../../../lib/components/buttons/Button.js";
12
11
  import Modal from "../../../lib/components/overlays/Modal.js";
12
+ import { actionErrorMessage } from "../../shared/components/admin/elevation.js";
13
13
  const PAGE_SIZE = 25;
14
14
  export function readMailboxUid() {
15
15
  if (typeof window === "undefined")
@@ -37,7 +37,7 @@ function QuarantineContent({ userUid }) {
37
37
  // The administration scope: any mailbox's held mail, recorded in the audit log.
38
38
  listQuarantine(uid, { page, limit: PAGE_SIZE, scope: "admin" })
39
39
  .then(setEntries)
40
- .catch((err) => setError(err instanceof ApiRequestError ? err.message : "Could not load quarantine."))
40
+ .catch((err) => setError(actionErrorMessage(err, "Could not load quarantine.")))
41
41
  .finally(() => setLoading(false));
42
42
  }
43
43
  useEffect(() => {
@@ -63,7 +63,7 @@ function QuarantineContent({ userUid }) {
63
63
  reload(mailboxUid);
64
64
  }
65
65
  catch (err) {
66
- setReleaseError(err instanceof ApiRequestError ? err.message : "Could not mark this message released.");
66
+ setReleaseError(actionErrorMessage(err, "Could not mark this message released."));
67
67
  }
68
68
  finally {
69
69
  setReleasing(false);
@@ -4,11 +4,11 @@ import { jsx as _jsx } from "react/jsx-runtime";
4
4
  // SPDX-License-Identifier: MPL-2.0
5
5
  ///////////////////////////////////////////////////////////////////////////////
6
6
  import { useEffect, useState } from "react";
7
- import { ApiRequestError } from "../../../lib/util/api.js";
8
7
  import { getRetentionPolicy } from "../../../lib/admin/retentionPolicyApi.js";
9
8
  import AdminShell from "../../shared/components/admin/layout/AdminShell.js";
10
9
  import RetentionPolicyForm from "../../shared/components/admin/settings/RetentionPolicyForm.js";
11
- import Alert from "../../../lib/components/feedback/Alert.js";
10
+ import Alert from "../../shared/components/admin/ActionAlert.js";
11
+ import { actionErrorMessage } from "../../shared/components/admin/elevation.js";
12
12
  export default function RetentionPolicyPage(props) {
13
13
  return (_jsx(AdminShell, { ...props, active: "retentionPolicy", children: _jsx(RetentionPolicyContent, {}) }));
14
14
  }
@@ -19,7 +19,7 @@ function RetentionPolicyContent() {
19
19
  useEffect(() => {
20
20
  getRetentionPolicy()
21
21
  .then(setPolicy)
22
- .catch((err) => setLoadError(err instanceof ApiRequestError ? err.message : "Could not load the retention policy."))
22
+ .catch((err) => setLoadError(actionErrorMessage(err, "Could not load the retention policy.")))
23
23
  .finally(() => setLoading(false));
24
24
  }, []);
25
25
  if (loading) {
@@ -4,17 +4,17 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
4
4
  // SPDX-License-Identifier: MPL-2.0
5
5
  ///////////////////////////////////////////////////////////////////////////////
6
6
  import { useEffect, useRef, useState } from "react";
7
- import { ApiRequestError } from "../../../lib/util/api.js";
7
+ import { actionErrorMessage } from "../../shared/components/admin/elevation.js";
8
8
  import { getSigningEnrollmentInfo, listSigningEnrollments, looksLikePemCertificate, rejectSigningEnrollment, signingEnrollmentCsrUrl, uploadSigningEnrollmentCertificate, } from "../../../lib/crypto/signingProviderApi.js";
9
9
  import AdminShell from "../../shared/components/admin/layout/AdminShell.js";
10
- import Alert from "../../../lib/components/feedback/Alert.js";
10
+ import Alert from "../../shared/components/admin/ActionAlert.js";
11
11
  import Button from "../../../lib/components/buttons/Button.js";
12
12
  import Modal from "../../../lib/components/overlays/Modal.js";
13
13
  import { notify } from "../../shared/notifications/store.js";
14
14
  const INPUT_CLASS = "text-sm border border-border rounded-sm py-1.5 px-2 bg-surface";
15
15
  const TEXTAREA_CLASS = `${INPUT_CLASS} font-mono text-xs`;
16
16
  function errorMessage(err, fallback) {
17
- return err instanceof ApiRequestError ? err.message : fallback;
17
+ return actionErrorMessage(err, fallback);
18
18
  }
19
19
  function statusBadgeClass(status) {
20
20
  if (status === "failed")