@rapidmx/web-client 0.14.1 → 0.16.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 (314) hide show
  1. package/README.md +373 -373
  2. package/apps/admin/branding/index.tsx +39 -39
  3. package/apps/admin/data-requests/index.tsx +482 -480
  4. package/apps/admin/domains/[uid].tsx +164 -163
  5. package/apps/admin/escrow-scopes/[uid].tsx +348 -348
  6. package/apps/admin/index.tsx +127 -124
  7. package/apps/admin/mailboxes/[uid].tsx +269 -224
  8. package/apps/admin/mailboxes/new/index.tsx +28 -28
  9. package/apps/admin/plugins/index.tsx +15 -15
  10. package/apps/admin/retention-policy/index.tsx +39 -39
  11. package/apps/admin/signing-certificates/index.tsx +343 -343
  12. package/apps/escrow/audit-log/index.tsx +196 -196
  13. package/apps/escrow/matters/[uid].tsx +621 -621
  14. package/apps/shared/appearance/AppearanceForm.tsx +9 -1
  15. package/apps/shared/auth/adminAccess.ts +99 -99
  16. package/apps/shared/calendar/bookingPlugin.ts +100 -0
  17. package/apps/shared/calendar/calendarLiveUpdates.ts +27 -0
  18. package/apps/shared/components/admin/layout/AdminShell.tsx +378 -346
  19. package/apps/shared/components/admin/mailboxes/EraseLeftoverDataDialog.tsx +238 -0
  20. package/apps/shared/components/admin/mailboxes/EscrowScopeCard.tsx +152 -152
  21. package/apps/shared/components/admin/mailboxes/LeftoverMailboxesSection.tsx +194 -0
  22. package/apps/shared/components/admin/settings/BrandingForm.tsx +423 -423
  23. package/apps/shared/components/admin/settings/EncryptionPolicyForm.tsx +119 -119
  24. package/apps/shared/components/admin/settings/MailboxCreateForm.tsx +53 -4
  25. package/apps/shared/components/admin/settings/MailboxPolicyForm.tsx +198 -198
  26. package/apps/shared/components/admin/settings/PluginsManager.tsx +64 -10
  27. package/apps/shared/components/admin/settings/RetentionPolicyForm.tsx +182 -182
  28. package/apps/shared/components/admin/setup/EscrowSetupStep.tsx +288 -288
  29. package/apps/shared/components/admin/setup/SetupWizard.tsx +444 -444
  30. package/apps/shared/components/admin/usePagedList.tsx +129 -129
  31. package/apps/shared/components/calendar/AppointmentQuickForm.tsx +327 -0
  32. package/apps/shared/components/calendar/DescriptionEditor.tsx +274 -0
  33. package/apps/shared/components/calendar/EventDescriptionView.tsx +70 -0
  34. package/apps/shared/components/calendar/EventDetails.tsx +401 -0
  35. package/apps/shared/components/calendar/EventEditor.tsx +635 -0
  36. package/apps/shared/components/calendar/EventExpandedForm.tsx +210 -0
  37. package/apps/shared/components/calendar/EventFormParts.tsx +591 -0
  38. package/apps/shared/components/calendar/EventModal.tsx +206 -946
  39. package/apps/shared/components/calendar/EventQuickForm.tsx +116 -0
  40. package/apps/shared/components/calendar/EventShell.tsx +202 -0
  41. package/apps/shared/components/calendar/FindATime.tsx +379 -0
  42. package/apps/shared/components/calendar/GuestInput.tsx +100 -0
  43. package/apps/shared/components/calendar/LazyDescriptionEditor.tsx +70 -0
  44. package/apps/shared/components/calendar/MonthView.tsx +185 -173
  45. package/apps/shared/components/calendar/QuickCreateFaces.tsx +87 -0
  46. package/apps/shared/components/calendar/QuickCreateTabs.tsx +81 -0
  47. package/apps/shared/components/calendar/QuickFaceFrame.tsx +81 -0
  48. package/apps/shared/components/calendar/RecurrenceEditor.tsx +227 -222
  49. package/apps/shared/components/calendar/RequestChangeForm.tsx +240 -0
  50. package/apps/shared/components/calendar/SplitDayView.tsx +144 -143
  51. package/apps/shared/components/calendar/TaskQuickForm.tsx +289 -0
  52. package/apps/shared/components/calendar/TimeGridView.tsx +246 -244
  53. package/apps/shared/components/calendar/allDay.ts +124 -124
  54. package/apps/shared/components/calendar/eventDialogFields.ts +86 -0
  55. package/apps/shared/components/calendar/eventForm.ts +108 -0
  56. package/apps/shared/components/calendar/eventFormat.ts +210 -0
  57. package/apps/shared/components/calendar/findTimeGrid.ts +90 -0
  58. package/apps/shared/components/calendar/layout/CalendarShell.tsx +201 -200
  59. package/apps/shared/components/calendar/swipeNavigation.ts +14 -0
  60. package/apps/shared/components/contacts/ContactForm.tsx +383 -383
  61. package/apps/shared/components/contacts/ContactsSidebar.tsx +1 -1
  62. package/apps/shared/components/contacts/ContactsToolbar.tsx +103 -98
  63. package/apps/shared/components/contacts/layout/ContactsShell.tsx +217 -216
  64. package/apps/shared/components/escrow/layout/EscrowShell.tsx +155 -155
  65. package/apps/shared/components/layout/AppShell.tsx +480 -480
  66. package/apps/shared/components/layout/FloatingActionButton.tsx +31 -0
  67. package/apps/shared/components/layout/KeyEnrollmentGate.tsx +398 -398
  68. package/apps/shared/components/layout/MailboxProvisioning.tsx +168 -168
  69. package/apps/shared/components/layout/ResponsiveToolbar.tsx +315 -315
  70. package/apps/shared/components/layout/ThemeSwitch.tsx +84 -84
  71. package/apps/shared/components/layout/UserMenu.tsx +439 -372
  72. package/apps/shared/components/mail/ConversationList.tsx +323 -271
  73. package/apps/shared/components/mail/ConversationThreadPane.tsx +130 -5
  74. package/apps/shared/components/mail/InviteCard.tsx +387 -0
  75. package/apps/shared/components/mail/MailSelectionBar.tsx +236 -227
  76. package/apps/shared/components/mail/MessageDetailPane.tsx +1559 -1537
  77. package/apps/shared/components/mail/SwipeRow.tsx +120 -0
  78. package/apps/shared/components/mail/compose/ComposeContext.tsx +312 -312
  79. package/apps/shared/components/mail/compose/ComposeToolbar.tsx +422 -422
  80. package/apps/shared/components/mail/compose/ComposeWindow.tsx +1681 -1673
  81. package/apps/shared/components/mail/compose/RecipientInput.tsx +54 -11
  82. package/apps/shared/components/mail/compose/RichTextEditor.tsx +147 -147
  83. package/apps/shared/components/mail/compose/composeFlushRegistry.ts +60 -60
  84. package/apps/shared/components/mail/compose/quotedBody.ts +161 -161
  85. package/apps/shared/components/mail/invite/InviteRowChip.tsx +104 -0
  86. package/apps/shared/components/mail/invite/InviteRsvpPopover.tsx +271 -0
  87. package/apps/shared/components/mail/invite/InviteTimeline.tsx +200 -0
  88. package/apps/shared/components/mail/invite/ProposeTimeForm.tsx +109 -0
  89. package/apps/shared/components/mail/invite/inviteFormat.ts +110 -0
  90. package/apps/shared/components/mail/invite/inviteStore.ts +114 -0
  91. package/apps/shared/components/mail/layout/FolderBadgeChip.tsx +21 -0
  92. package/apps/shared/components/mail/layout/MailShell.tsx +546 -490
  93. package/apps/shared/components/mail/layout/SidebarSection.tsx +66 -0
  94. package/apps/shared/components/mail/reading/PendingMessageCard.tsx +68 -0
  95. package/apps/shared/components/mail/verificationSeals.ts +125 -125
  96. package/apps/shared/components/rules/RuleBuilder.tsx +311 -311
  97. package/apps/shared/components/settings/SigningCertificateCard.tsx +344 -344
  98. package/apps/shared/components/settings/layout/SettingsShell.tsx +255 -253
  99. package/apps/shared/components/tasks/TasksSidebar.tsx +1 -1
  100. package/apps/shared/components/tasks/layout/TasksShell.tsx +218 -217
  101. package/apps/shared/gestures/useEnterSlide.ts +54 -0
  102. package/apps/shared/gestures/useSwipe.ts +114 -0
  103. package/apps/shared/gestures/useSwipeSlide.ts +113 -0
  104. package/apps/shared/gestures/useWheelPaging.ts +107 -0
  105. package/apps/shared/keyboard/GlobalShortcuts.tsx +51 -51
  106. package/apps/shared/keyboard/ShortcutProvider.tsx +62 -62
  107. package/apps/shared/keyboard/ShortcutsDialog.tsx +84 -84
  108. package/apps/shared/keyboard/dispatch.ts +124 -124
  109. package/apps/shared/keyboard/format.ts +89 -89
  110. package/apps/shared/keyboard/keymap.ts +114 -114
  111. package/apps/shared/keyboard/registry.ts +65 -65
  112. package/apps/shared/keyboard/targets.ts +79 -79
  113. package/apps/shared/mail/folderCounts.ts +17 -0
  114. package/apps/shared/mail/folderTree.ts +143 -143
  115. package/apps/shared/mail/listAllPages.ts +39 -39
  116. package/apps/shared/mail/newMailNotifications.ts +3 -15
  117. package/apps/shared/mail/outbox/outgoingReplies.ts +192 -0
  118. package/apps/shared/mail/outbox/sendJob.ts +19 -1
  119. package/apps/shared/mail/outbox/sendOutcomes.ts +13 -4
  120. package/apps/shared/mail/primaryMailbox.ts +71 -0
  121. package/apps/shared/mail/useCollapsedSections.ts +146 -0
  122. package/apps/shared/mail/useMailConnection.ts +205 -203
  123. package/apps/shared/mail/useMailLiveUpdates.ts +277 -277
  124. package/apps/shared/mail/useMarkMessageRead.ts +47 -47
  125. package/apps/shared/mail/useNewMailNotifications.ts +2 -2
  126. package/apps/shared/navigation/AppRouter.tsx +300 -300
  127. package/apps/shared/navigation/routerContext.tsx +83 -83
  128. package/apps/shared/notifications/preferences.ts +36 -0
  129. package/apps/shared/notifications/store.ts +9 -0
  130. package/apps/shared/search/LocalIndexLifecycle.tsx +114 -114
  131. package/apps/shared/search/crossMailboxSearch.ts +169 -0
  132. package/apps/shared/search/localIndexBuilder.ts +481 -481
  133. package/apps/shared/signing/enrollmentStorage.ts +33 -33
  134. package/apps/shared/signing/enrollmentTracker.ts +385 -385
  135. package/apps/shared/signing/enrollmentView.ts +251 -251
  136. package/apps/shared/signing/useNow.ts +19 -19
  137. package/apps/shared/signing/useSigningEnrollmentWatcher.ts +90 -90
  138. package/apps/shared/styles/app.css +396 -386
  139. package/apps/www/_routes.ts +1 -0
  140. package/apps/www/calendar/index.tsx +578 -469
  141. package/apps/www/contacts/[uid].tsx +109 -109
  142. package/apps/www/contacts/index.tsx +6 -0
  143. package/apps/www/index.tsx +2847 -2332
  144. package/apps/www/messages/[uid].tsx +135 -108
  145. package/apps/www/settings/auto-reply/index.tsx +133 -133
  146. package/apps/www/settings/encryption/index.tsx +1287 -1287
  147. package/apps/www/settings/filters/[uid].tsx +176 -176
  148. package/apps/www/settings/filters/index.tsx +102 -102
  149. package/apps/www/settings/filters/new/index.tsx +140 -140
  150. package/apps/www/settings/labels/index.tsx +204 -204
  151. package/apps/www/settings/privacy/index.tsx +492 -492
  152. package/apps/www/settings/profile/index.tsx +248 -0
  153. package/apps/www/settings/read-receipts/index.tsx +147 -147
  154. package/apps/www/settings/sharing/index.tsx +256 -256
  155. package/apps/www/settings/signatures/[uid].tsx +172 -172
  156. package/apps/www/settings/signatures/index.tsx +88 -88
  157. package/apps/www/settings/signatures/new/index.tsx +135 -135
  158. package/apps/www/tasks/index.tsx +649 -649
  159. package/dist/apps/admin/data-requests/index.js +1 -1
  160. package/dist/apps/admin/domains/[uid].js +4 -2
  161. package/dist/apps/admin/index.js +2 -1
  162. package/dist/apps/admin/mailboxes/[uid].js +12 -2
  163. package/dist/apps/shared/appearance/AppearanceForm.js +9 -1
  164. package/dist/apps/shared/calendar/bookingPlugin.d.ts +50 -0
  165. package/dist/apps/shared/calendar/bookingPlugin.js +57 -0
  166. package/dist/apps/shared/calendar/calendarLiveUpdates.d.ts +11 -0
  167. package/dist/apps/shared/calendar/calendarLiveUpdates.js +23 -0
  168. package/dist/apps/shared/components/admin/layout/AdminShell.d.ts +1 -1
  169. package/dist/apps/shared/components/admin/layout/AdminShell.js +7 -3
  170. package/dist/apps/shared/components/admin/mailboxes/EraseLeftoverDataDialog.d.ts +35 -0
  171. package/dist/apps/shared/components/admin/mailboxes/EraseLeftoverDataDialog.js +115 -0
  172. package/dist/apps/shared/components/admin/mailboxes/LeftoverMailboxesSection.d.ts +16 -0
  173. package/dist/apps/shared/components/admin/mailboxes/LeftoverMailboxesSection.js +92 -0
  174. package/dist/apps/shared/components/admin/settings/BrandingForm.js +3 -3
  175. package/dist/apps/shared/components/admin/settings/MailboxCreateForm.js +28 -4
  176. package/dist/apps/shared/components/admin/settings/PluginsManager.js +40 -6
  177. package/dist/apps/shared/components/calendar/AppointmentQuickForm.d.ts +47 -0
  178. package/dist/apps/shared/components/calendar/AppointmentQuickForm.js +135 -0
  179. package/dist/apps/shared/components/calendar/DescriptionEditor.d.ts +26 -0
  180. package/dist/apps/shared/components/calendar/DescriptionEditor.js +192 -0
  181. package/dist/apps/shared/components/calendar/EventDescriptionView.d.ts +14 -0
  182. package/dist/apps/shared/components/calendar/EventDescriptionView.js +39 -0
  183. package/dist/apps/shared/components/calendar/EventDetails.d.ts +33 -0
  184. package/dist/apps/shared/components/calendar/EventDetails.js +137 -0
  185. package/dist/apps/shared/components/calendar/EventEditor.d.ts +59 -0
  186. package/dist/apps/shared/components/calendar/EventEditor.js +544 -0
  187. package/dist/apps/shared/components/calendar/EventExpandedForm.d.ts +14 -0
  188. package/dist/apps/shared/components/calendar/EventExpandedForm.js +44 -0
  189. package/dist/apps/shared/components/calendar/EventFormParts.d.ts +70 -0
  190. package/dist/apps/shared/components/calendar/EventFormParts.js +191 -0
  191. package/dist/apps/shared/components/calendar/EventModal.d.ts +26 -13
  192. package/dist/apps/shared/components/calendar/EventModal.js +57 -459
  193. package/dist/apps/shared/components/calendar/EventQuickForm.d.ts +18 -0
  194. package/dist/apps/shared/components/calendar/EventQuickForm.js +25 -0
  195. package/dist/apps/shared/components/calendar/EventShell.d.ts +64 -0
  196. package/dist/apps/shared/components/calendar/EventShell.js +134 -0
  197. package/dist/apps/shared/components/calendar/FindATime.d.ts +18 -0
  198. package/dist/apps/shared/components/calendar/FindATime.js +190 -0
  199. package/dist/apps/shared/components/calendar/GuestInput.d.ts +45 -0
  200. package/dist/apps/shared/components/calendar/GuestInput.js +30 -0
  201. package/dist/apps/shared/components/calendar/LazyDescriptionEditor.d.ts +8 -0
  202. package/dist/apps/shared/components/calendar/LazyDescriptionEditor.js +44 -0
  203. package/dist/apps/shared/components/calendar/MonthView.d.ts +5 -1
  204. package/dist/apps/shared/components/calendar/MonthView.js +11 -5
  205. package/dist/apps/shared/components/calendar/QuickCreateFaces.d.ts +30 -0
  206. package/dist/apps/shared/components/calendar/QuickCreateFaces.js +44 -0
  207. package/dist/apps/shared/components/calendar/QuickCreateTabs.d.ts +24 -0
  208. package/dist/apps/shared/components/calendar/QuickCreateTabs.js +46 -0
  209. package/dist/apps/shared/components/calendar/QuickFaceFrame.d.ts +25 -0
  210. package/dist/apps/shared/components/calendar/QuickFaceFrame.js +19 -0
  211. package/dist/apps/shared/components/calendar/RecurrenceEditor.d.ts +4 -1
  212. package/dist/apps/shared/components/calendar/RecurrenceEditor.js +2 -2
  213. package/dist/apps/shared/components/calendar/RequestChangeForm.d.ts +36 -0
  214. package/dist/apps/shared/components/calendar/RequestChangeForm.js +127 -0
  215. package/dist/apps/shared/components/calendar/SplitDayView.d.ts +3 -2
  216. package/dist/apps/shared/components/calendar/SplitDayView.js +3 -2
  217. package/dist/apps/shared/components/calendar/TaskQuickForm.d.ts +40 -0
  218. package/dist/apps/shared/components/calendar/TaskQuickForm.js +101 -0
  219. package/dist/apps/shared/components/calendar/TimeGridView.d.ts +4 -2
  220. package/dist/apps/shared/components/calendar/TimeGridView.js +3 -2
  221. package/dist/apps/shared/components/calendar/eventDialogFields.d.ts +28 -0
  222. package/dist/apps/shared/components/calendar/eventDialogFields.js +59 -0
  223. package/dist/apps/shared/components/calendar/eventForm.d.ts +98 -0
  224. package/dist/apps/shared/components/calendar/eventForm.js +1 -0
  225. package/dist/apps/shared/components/calendar/eventFormat.d.ts +80 -0
  226. package/dist/apps/shared/components/calendar/eventFormat.js +190 -0
  227. package/dist/apps/shared/components/calendar/findTimeGrid.d.ts +30 -0
  228. package/dist/apps/shared/components/calendar/findTimeGrid.js +83 -0
  229. package/dist/apps/shared/components/calendar/layout/CalendarShell.js +3 -2
  230. package/dist/apps/shared/components/calendar/swipeNavigation.d.ts +9 -0
  231. package/dist/apps/shared/components/calendar/swipeNavigation.js +8 -0
  232. package/dist/apps/shared/components/contacts/ContactsSidebar.js +1 -1
  233. package/dist/apps/shared/components/contacts/ContactsToolbar.d.ts +3 -1
  234. package/dist/apps/shared/components/contacts/ContactsToolbar.js +4 -2
  235. package/dist/apps/shared/components/contacts/layout/ContactsShell.js +4 -3
  236. package/dist/apps/shared/components/layout/FloatingActionButton.d.ts +13 -0
  237. package/dist/apps/shared/components/layout/FloatingActionButton.js +9 -0
  238. package/dist/apps/shared/components/layout/UserMenu.d.ts +14 -9
  239. package/dist/apps/shared/components/layout/UserMenu.js +74 -26
  240. package/dist/apps/shared/components/mail/ConversationList.d.ts +12 -1
  241. package/dist/apps/shared/components/mail/ConversationList.js +21 -4
  242. package/dist/apps/shared/components/mail/ConversationThreadPane.d.ts +4 -1
  243. package/dist/apps/shared/components/mail/ConversationThreadPane.js +127 -22
  244. package/dist/apps/shared/components/mail/InviteCard.d.ts +20 -0
  245. package/dist/apps/shared/components/mail/InviteCard.js +150 -0
  246. package/dist/apps/shared/components/mail/MailSelectionBar.d.ts +6 -1
  247. package/dist/apps/shared/components/mail/MailSelectionBar.js +3 -3
  248. package/dist/apps/shared/components/mail/MessageDetailPane.js +13 -2
  249. package/dist/apps/shared/components/mail/SwipeRow.d.ts +22 -0
  250. package/dist/apps/shared/components/mail/SwipeRow.js +71 -0
  251. package/dist/apps/shared/components/mail/compose/ComposeWindow.js +16 -7
  252. package/dist/apps/shared/components/mail/compose/RecipientInput.d.ts +21 -1
  253. package/dist/apps/shared/components/mail/compose/RecipientInput.js +18 -10
  254. package/dist/apps/shared/components/mail/invite/InviteRowChip.d.ts +23 -0
  255. package/dist/apps/shared/components/mail/invite/InviteRowChip.js +46 -0
  256. package/dist/apps/shared/components/mail/invite/InviteRsvpPopover.d.ts +20 -0
  257. package/dist/apps/shared/components/mail/invite/InviteRsvpPopover.js +141 -0
  258. package/dist/apps/shared/components/mail/invite/InviteTimeline.d.ts +27 -0
  259. package/dist/apps/shared/components/mail/invite/InviteTimeline.js +120 -0
  260. package/dist/apps/shared/components/mail/invite/ProposeTimeForm.d.ts +17 -0
  261. package/dist/apps/shared/components/mail/invite/ProposeTimeForm.js +45 -0
  262. package/dist/apps/shared/components/mail/invite/inviteFormat.d.ts +28 -0
  263. package/dist/apps/shared/components/mail/invite/inviteFormat.js +94 -0
  264. package/dist/apps/shared/components/mail/invite/inviteStore.d.ts +28 -0
  265. package/dist/apps/shared/components/mail/invite/inviteStore.js +95 -0
  266. package/dist/apps/shared/components/mail/layout/FolderBadgeChip.d.ts +6 -0
  267. package/dist/apps/shared/components/mail/layout/FolderBadgeChip.js +9 -0
  268. package/dist/apps/shared/components/mail/layout/MailShell.d.ts +10 -0
  269. package/dist/apps/shared/components/mail/layout/MailShell.js +76 -46
  270. package/dist/apps/shared/components/mail/layout/SidebarSection.d.ts +23 -0
  271. package/dist/apps/shared/components/mail/layout/SidebarSection.js +16 -0
  272. package/dist/apps/shared/components/mail/reading/PendingMessageCard.d.ts +14 -0
  273. package/dist/apps/shared/components/mail/reading/PendingMessageCard.js +16 -0
  274. package/dist/apps/shared/components/settings/layout/SettingsShell.js +7 -5
  275. package/dist/apps/shared/components/tasks/TasksSidebar.js +1 -1
  276. package/dist/apps/shared/components/tasks/layout/TasksShell.js +4 -3
  277. package/dist/apps/shared/gestures/useEnterSlide.d.ts +14 -0
  278. package/dist/apps/shared/gestures/useEnterSlide.js +47 -0
  279. package/dist/apps/shared/gestures/useSwipe.d.ts +45 -0
  280. package/dist/apps/shared/gestures/useSwipe.js +90 -0
  281. package/dist/apps/shared/gestures/useSwipeSlide.d.ts +40 -0
  282. package/dist/apps/shared/gestures/useSwipeSlide.js +95 -0
  283. package/dist/apps/shared/gestures/useWheelPaging.d.ts +32 -0
  284. package/dist/apps/shared/gestures/useWheelPaging.js +85 -0
  285. package/dist/apps/shared/mail/folderCounts.d.ts +10 -0
  286. package/dist/apps/shared/mail/folderCounts.js +12 -0
  287. package/dist/apps/shared/mail/newMailNotifications.d.ts +3 -8
  288. package/dist/apps/shared/mail/newMailNotifications.js +3 -12
  289. package/dist/apps/shared/mail/outbox/outgoingReplies.d.ts +80 -0
  290. package/dist/apps/shared/mail/outbox/outgoingReplies.js +131 -0
  291. package/dist/apps/shared/mail/outbox/sendJob.d.ts +5 -1
  292. package/dist/apps/shared/mail/outbox/sendJob.js +14 -1
  293. package/dist/apps/shared/mail/outbox/sendOutcomes.js +13 -4
  294. package/dist/apps/shared/mail/primaryMailbox.d.ts +29 -0
  295. package/dist/apps/shared/mail/primaryMailbox.js +61 -0
  296. package/dist/apps/shared/mail/useCollapsedSections.d.ts +32 -0
  297. package/dist/apps/shared/mail/useCollapsedSections.js +110 -0
  298. package/dist/apps/shared/mail/useMailConnection.js +3 -1
  299. package/dist/apps/shared/mail/useNewMailNotifications.js +3 -2
  300. package/dist/apps/shared/notifications/preferences.d.ts +13 -0
  301. package/dist/apps/shared/notifications/preferences.js +36 -0
  302. package/dist/apps/shared/notifications/store.d.ts +1 -0
  303. package/dist/apps/shared/notifications/store.js +7 -23
  304. package/dist/apps/shared/search/crossMailboxSearch.d.ts +72 -0
  305. package/dist/apps/shared/search/crossMailboxSearch.js +136 -0
  306. package/dist/apps/shared/styles/app.css +396 -386
  307. package/dist/apps/www/_routes.js +1 -0
  308. package/dist/apps/www/calendar/index.js +78 -7
  309. package/dist/apps/www/contacts/index.js +3 -1
  310. package/dist/apps/www/index.js +548 -210
  311. package/dist/apps/www/messages/[uid].js +13 -5
  312. package/dist/apps/www/settings/profile/index.d.ts +4 -0
  313. package/dist/apps/www/settings/profile/index.js +124 -0
  314. package/package.json +2 -2
@@ -1,227 +1,236 @@
1
- ///////////////////////////////////////////////////////////////////////////////
2
- // Copyright (C) 2026 Jean-Philippe Steinmetz
3
- // SPDX-License-Identifier: MPL-2.0
4
- ///////////////////////////////////////////////////////////////////////////////
5
- import React, { useState } from "react";
6
- import { Folder, Message } from "@rapidmx/react-shared/mail/mailApi.js";
7
- import { Label } from "@rapidmx/react-shared/mail/labelsApi.js";
8
- import LabelMenuButton from "./labelMenu.js";
9
- import MoveToFolderDialog, { MOVE_TARGET_TYPES } from "./MoveToFolderDialog.js";
10
- import { ariaKeyShortcuts, withHint } from "../../keyboard/format.js";
11
- import { SHORTCUTS, ShortcutDef } from "../../keyboard/keymap.js";
12
- import { useKeyEnvironment } from "../../keyboard/ShortcutProvider.js";
13
-
14
- export interface MailSelectionBarProps {
15
- selected: Message[];
16
- /** Every message currently listed - what "Select all" selects and what `allSelected` is measured against. */
17
- listed: Message[];
18
- /** What the bar *counts*, when the rows being ticked aren't messages themselves: the conversation list
19
- * ticks conversations, each standing for several messages, so "3 conversations selected" is what the
20
- * reader picked while `selected` stays the messages every action below acts on. Left out by the flat
21
- * message list, which counts `selected`/`listed` directly. */
22
- totals?: { selected: number; listed: number; noun: string };
23
- onSelectAll: () => void;
24
- onClearSelection: () => void;
25
- /** Leaves select mode entirely (and clears the selection). */
26
- onCancel: () => void;
27
- folders: Folder[];
28
- currentFolderUid?: string;
29
- /** Every label this mailbox has, for the Apply label action. */
30
- labels: Label[];
31
- /** The mailbox a label created from Apply label belongs to. */
32
- mailboxUid: string;
33
- onLabelCreated: (label: Label) => void;
34
- /** A folder created from the Move to prompt, for the caller's own folder list and the sidebar. */
35
- onFolderCreated: (folder: Folder) => void;
36
- /** Sets the selection's labels: every message ends up with `labelUids`, plus whichever of
37
- * `keepPartial` it already had (those rows were left partially applied, so each message keeps what
38
- * it has). */
39
- onApplyLabels: (labelUids: string[], keepPartial: string[]) => void;
40
- onSetRead: (read: boolean) => void;
41
- onSetFlagged: (flagged: boolean) => void;
42
- onArchive: () => void;
43
- /** Moves the selection into `folderUid`, resolving once the bulk update has settled. It resolves
44
- * whether or not that update was rejected: a bulk update is applied element by element, so a failure
45
- * is explained by a pop-up (see `notifyApiError()`), raised by the page along with the reload it triggers, rather than in the
46
- * prompt, which would be claiming the move simply didn't happen. */
47
- onMoveTo: (folderUid: string) => Promise<void>;
48
- onReportJunk: () => void;
49
- onDelete: () => void;
50
- /** A bulk action is in flight - every action is held until it settles, since the next one would send
51
- * `version`s the first has already superseded. */
52
- busy: boolean;
53
- /** The keyboard acts on this selection (Delete, Ctrl+Q, Ctrl+U, Insert - registered by the page): Mark read, Mark unread, Flag and
54
- * Delete name their shortcut in the tooltip and `aria-keyshortcuts`. */
55
- shortcuts?: boolean;
56
- }
57
-
58
- function actionClassName(): string {
59
- return "px-2 py-1 rounded-md text-sm text-text hover:bg-surface-alt disabled:opacity-50 disabled:hover:bg-transparent";
60
- }
61
-
62
- /**
63
- * The header that replaces the list's own toolbar while select mode is on: how many rows are selected,
64
- * select-all/clear, and the bulk actions Outlook offers for a multi-selection - mark read/unread, flag,
65
- * archive, move, report junk and delete.
66
- *
67
- * "Delete" means *move to Deleted Items*, never a permanent erase: there is no bulk permanent-delete API,
68
- * and the collection-level DELETE truncates the folder rather than removing a selection. An action whose
69
- * target folder is the one already being viewed is disabled with a reason rather than hidden, so the set
70
- * of actions doesn't shift around between folders.
71
- */
72
- export default function MailSelectionBar({
73
- selected,
74
- listed,
75
- totals,
76
- onSelectAll,
77
- onClearSelection,
78
- onCancel,
79
- folders,
80
- currentFolderUid,
81
- labels,
82
- mailboxUid,
83
- onLabelCreated,
84
- onFolderCreated,
85
- onApplyLabels,
86
- onSetRead,
87
- onSetFlagged,
88
- onArchive,
89
- onMoveTo,
90
- onReportJunk,
91
- onDelete,
92
- busy,
93
- shortcuts,
94
- }: MailSelectionBarProps) {
95
- const env = useKeyEnvironment();
96
- /** `title` and `aria-keyshortcuts` for an action the keyboard also does; `reason` (why it is disabled) wins the tooltip. */
97
- const hint = (label: string, shortcut: ShortcutDef, reason?: string) =>
98
- shortcuts
99
- ? { title: reason ?? withHint(label, shortcut, env), "aria-keyshortcuts": ariaKeyShortcuts(shortcut, env) }
100
- : { title: reason };
101
- const selectedCount = totals?.selected ?? selected.length;
102
- const listedCount = totals?.listed ?? listed.length;
103
- // Counted on the rows that were ticked, but *emptied* on the messages: a ticked conversation whose
104
- // messages are still being fetched has nothing for an action to act on yet.
105
- const none = selectedCount === 0 || selected.length === 0;
106
- const allSelected = listedCount > 0 && selectedCount === listedCount;
107
- const currentType = folders.find((folder) => folder.uid === currentFolderUid)?.type;
108
- const moveTargets = folders.filter((folder) => MOVE_TARGET_TYPES.has(folder.type) && folder.uid !== currentFolderUid);
109
- // The same prompt the reading pane's own Move to opens, so one list of destinations and one way to
110
- // create a folder serve both.
111
- const [movePrompt, setMovePrompt] = useState(false);
112
-
113
- // None of the three needs its folder to exist first - the caller creates or lazily provisions it (see
114
- // `resolveFolderOfType()` and `bulkArchive()` in `apps/www/index.tsx`) - so the only thing that disables
115
- // them is already being in the folder they would move to.
116
- const archiveReason = currentType === "archive" ? "These messages are already in Archive" : undefined;
117
- const junkReason = currentType === "junk" ? "These messages are already in Junk" : undefined;
118
- const deleteReason = currentType === "deleted_items" ? "These messages are already in Deleted Items" : undefined;
119
-
120
- // A label every selected message already carries starts ticked; one only some of them carry starts
121
- // partially applied, and is left exactly as it is unless the reader touches that row.
122
- const appliedToAll = labels.filter((label) => !none && selected.every((m) => m.labelUids?.includes(label.uid)));
123
- const appliedToSome = labels.filter(
124
- (label) => selected.some((m) => m.labelUids?.includes(label.uid)) && !appliedToAll.includes(label),
125
- );
126
-
127
-
128
- return (
129
- <div className="border-b border-border">
130
- <MoveToFolderDialog
131
- open={movePrompt}
132
- onClose={() => setMovePrompt(false)}
133
- mailboxUid={mailboxUid}
134
- folders={folders}
135
- currentFolderUid={currentFolderUid}
136
- count={selected.length}
137
- onMove={onMoveTo}
138
- onFolderCreated={onFolderCreated}
139
- />
140
- <div className="flex items-center gap-2 px-3 py-1.5 bg-surface-alt">
141
- <span aria-live="polite" className="text-sm font-semibold text-text">
142
- {selectedCount}
143
- {totals ? ` ${totals.noun}${selectedCount === 1 ? "" : "s"}` : ""} selected
144
- </span>
145
- <button type="button" onClick={onSelectAll} disabled={allSelected || listedCount === 0} className={actionClassName()}>
146
- Select all
147
- </button>
148
- <button type="button" onClick={onClearSelection} disabled={selectedCount === 0} className={actionClassName()}>
149
- Clear
150
- </button>
151
- <button type="button" onClick={onCancel} className={`${actionClassName()} ml-auto`}>
152
- Cancel
153
- </button>
154
- </div>
155
- <div className="flex flex-wrap items-center gap-0.5 px-1.5 py-1">
156
- <button type="button" onClick={() => onSetRead(true)} disabled={none || busy} className={actionClassName()} {...hint("Mark read", SHORTCUTS.mail.markRead)}>
157
- Mark read
158
- </button>
159
- <button type="button" onClick={() => onSetRead(false)} disabled={none || busy} className={actionClassName()} {...hint("Mark unread", SHORTCUTS.mail.markUnread)}>
160
- Mark unread
161
- </button>
162
- <button type="button" onClick={() => onSetFlagged(true)} disabled={none || busy} className={actionClassName()} {...hint("Flag", SHORTCUTS.mail.flag)}>
163
- Flag
164
- </button>
165
- <button type="button" onClick={() => onSetFlagged(false)} disabled={none || busy} className={actionClassName()}>
166
- Unflag
167
- </button>
168
- <button
169
- type="button"
170
- onClick={onArchive}
171
- disabled={none || busy || !!archiveReason}
172
- title={archiveReason}
173
- className={actionClassName()}
174
- >
175
- Archive
176
- </button>
177
- <LabelMenuButton
178
- aria-label="Apply label"
179
- label="Apply label"
180
- className="text-sm"
181
- labels={labels}
182
- mailboxUid={mailboxUid}
183
- onLabelCreated={onLabelCreated}
184
- applied={appliedToAll.map((label) => label.uid)}
185
- partial={appliedToSome.map((label) => label.uid)}
186
- onCommit={onApplyLabels}
187
- busy={busy}
188
- disabled={none || busy}
189
- note={
190
- selected.length === 1
191
- ? "Ticked labels are applied, unticked ones removed."
192
- : "Ticked labels are applied to every selected message and unticked ones removed from all of them; a dash means only some have that label, and leaving it alone keeps it that way."
193
- }
194
- emptyNote="This mailbox has no labels yet."
195
- commit={{ label: "Apply" }}
196
- clear={{ label: "Remove all labels" }}
197
- />
198
- <button
199
- type="button"
200
- onClick={() => setMovePrompt(true)}
201
- disabled={none || busy}
202
- className={actionClassName()}
203
- >
204
- Move to
205
- </button>
206
- <button
207
- type="button"
208
- onClick={onReportJunk}
209
- disabled={none || busy || !!junkReason}
210
- title={junkReason}
211
- className={actionClassName()}
212
- >
213
- Report junk
214
- </button>
215
- <button
216
- type="button"
217
- onClick={onDelete}
218
- disabled={none || busy || !!deleteReason}
219
- className={actionClassName()}
220
- {...hint("Delete", SHORTCUTS.mail.delete, deleteReason)}
221
- >
222
- Delete
223
- </button>
224
- </div>
225
- </div>
226
- );
227
- }
1
+ ///////////////////////////////////////////////////////////////////////////////
2
+ // Copyright (C) 2026 Jean-Philippe Steinmetz
3
+ // SPDX-License-Identifier: MPL-2.0
4
+ ///////////////////////////////////////////////////////////////////////////////
5
+ import React, { useState } from "react";
6
+ import { Folder, Message } from "@rapidmx/react-shared/mail/mailApi.js";
7
+ import { Label } from "@rapidmx/react-shared/mail/labelsApi.js";
8
+ import LabelMenuButton from "./labelMenu.js";
9
+ import MoveToFolderDialog, { MOVE_TARGET_TYPES } from "./MoveToFolderDialog.js";
10
+ import { ariaKeyShortcuts, withHint } from "../../keyboard/format.js";
11
+ import { SHORTCUTS, ShortcutDef } from "../../keyboard/keymap.js";
12
+ import { useKeyEnvironment } from "../../keyboard/ShortcutProvider.js";
13
+
14
+ export interface MailSelectionBarProps {
15
+ selected: Message[];
16
+ /** Every message currently listed - what "Select all" selects and what `allSelected` is measured against. */
17
+ listed: Message[];
18
+ /** What the bar *counts*, when the rows being ticked aren't messages themselves: the conversation list
19
+ * ticks conversations, each standing for several messages, so "3 conversations selected" is what the
20
+ * reader picked while `selected` stays the messages every action below acts on. Left out by the flat
21
+ * message list, which counts `selected`/`listed` directly. */
22
+ totals?: { selected: number; listed: number; noun: string };
23
+ onSelectAll: () => void;
24
+ onClearSelection: () => void;
25
+ /** Leaves select mode entirely (and clears the selection). */
26
+ onCancel: () => void;
27
+ folders: Folder[];
28
+ currentFolderUid?: string;
29
+ /** Every label this mailbox has, for the Apply label action. */
30
+ labels: Label[];
31
+ /** The mailbox a label created from Apply label belongs to. */
32
+ mailboxUid: string;
33
+ onLabelCreated: (label: Label) => void;
34
+ /** A folder created from the Move to prompt, for the caller's own folder list and the sidebar. */
35
+ onFolderCreated: (folder: Folder) => void;
36
+ /** Sets the selection's labels: every message ends up with `labelUids`, plus whichever of
37
+ * `keepPartial` it already had (those rows were left partially applied, so each message keeps what
38
+ * it has). */
39
+ onApplyLabels: (labelUids: string[], keepPartial: string[]) => void;
40
+ onSetRead: (read: boolean) => void;
41
+ onSetFlagged: (flagged: boolean) => void;
42
+ onArchive: () => void;
43
+ /** Moves the selection into `folderUid`, resolving once the bulk update has settled. It resolves
44
+ * whether or not that update was rejected: a bulk update is applied element by element, so a failure
45
+ * is explained by a pop-up (see `notifyApiError()`), raised by the page along with the reload it triggers, rather than in the
46
+ * prompt, which would be claiming the move simply didn't happen. */
47
+ onMoveTo: (folderUid: string) => Promise<void>;
48
+ onReportJunk: () => void;
49
+ onDelete: () => void;
50
+ /** A bulk action is in flight - every action is held until it settles, since the next one would send
51
+ * `version`s the first has already superseded. */
52
+ busy: boolean;
53
+ /** The keyboard acts on this selection (Delete, Ctrl+Q, Ctrl+U, Insert - registered by the page): Mark read, Mark unread, Flag and
54
+ * Delete name their shortcut in the tooltip and `aria-keyshortcuts`. */
55
+ shortcuts?: boolean;
56
+ /** Why Move to is unavailable, when the selection is spread over mailboxes and a folder can only belong to one (search results over several
57
+ * mailboxes). Shown as the button's tooltip. */
58
+ moveDisabledReason?: string;
59
+ /** The same for Apply label: a label belongs to one mailbox, and `labels` are one mailbox's. */
60
+ labelsDisabledReason?: string;
61
+ }
62
+
63
+ function actionClassName(): string {
64
+ return "px-2 py-1 rounded-md text-sm text-text hover:bg-surface-alt disabled:opacity-50 disabled:hover:bg-transparent";
65
+ }
66
+
67
+ /**
68
+ * The header that replaces the list's own toolbar while select mode is on: how many rows are selected,
69
+ * select-all/clear, and the bulk actions Outlook offers for a multi-selection - mark read/unread, flag,
70
+ * archive, move, report junk and delete.
71
+ *
72
+ * "Delete" means *move to Deleted Items*, never a permanent erase: there is no bulk permanent-delete API,
73
+ * and the collection-level DELETE truncates the folder rather than removing a selection. An action whose
74
+ * target folder is the one already being viewed is disabled with a reason rather than hidden, so the set
75
+ * of actions doesn't shift around between folders.
76
+ */
77
+ export default function MailSelectionBar({
78
+ selected,
79
+ listed,
80
+ totals,
81
+ onSelectAll,
82
+ onClearSelection,
83
+ onCancel,
84
+ folders,
85
+ currentFolderUid,
86
+ labels,
87
+ mailboxUid,
88
+ onLabelCreated,
89
+ onFolderCreated,
90
+ onApplyLabels,
91
+ onSetRead,
92
+ onSetFlagged,
93
+ onArchive,
94
+ onMoveTo,
95
+ onReportJunk,
96
+ onDelete,
97
+ busy,
98
+ shortcuts,
99
+ moveDisabledReason,
100
+ labelsDisabledReason,
101
+ }: MailSelectionBarProps) {
102
+ const env = useKeyEnvironment();
103
+ /** `title` and `aria-keyshortcuts` for an action the keyboard also does; `reason` (why it is disabled) wins the tooltip. */
104
+ const hint = (label: string, shortcut: ShortcutDef, reason?: string) =>
105
+ shortcuts
106
+ ? { title: reason ?? withHint(label, shortcut, env), "aria-keyshortcuts": ariaKeyShortcuts(shortcut, env) }
107
+ : { title: reason };
108
+ const selectedCount = totals?.selected ?? selected.length;
109
+ const listedCount = totals?.listed ?? listed.length;
110
+ // Counted on the rows that were ticked, but *emptied* on the messages: a ticked conversation whose
111
+ // messages are still being fetched has nothing for an action to act on yet.
112
+ const none = selectedCount === 0 || selected.length === 0;
113
+ const allSelected = listedCount > 0 && selectedCount === listedCount;
114
+ const currentType = folders.find((folder) => folder.uid === currentFolderUid)?.type;
115
+ const moveTargets = folders.filter((folder) => MOVE_TARGET_TYPES.has(folder.type) && folder.uid !== currentFolderUid);
116
+ // The same prompt the reading pane's own Move to opens, so one list of destinations and one way to
117
+ // create a folder serve both.
118
+ const [movePrompt, setMovePrompt] = useState(false);
119
+
120
+ // None of the three needs its folder to exist first - the caller creates or lazily provisions it (see
121
+ // `resolveFolderOfType()` and `bulkArchive()` in `apps/www/index.tsx`) - so the only thing that disables
122
+ // them is already being in the folder they would move to.
123
+ const archiveReason = currentType === "archive" ? "These messages are already in Archive" : undefined;
124
+ const junkReason = currentType === "junk" ? "These messages are already in Junk" : undefined;
125
+ const deleteReason = currentType === "deleted_items" ? "These messages are already in Deleted Items" : undefined;
126
+
127
+ // A label every selected message already carries starts ticked; one only some of them carry starts
128
+ // partially applied, and is left exactly as it is unless the reader touches that row.
129
+ const appliedToAll = labels.filter((label) => !none && selected.every((m) => m.labelUids?.includes(label.uid)));
130
+ const appliedToSome = labels.filter(
131
+ (label) => selected.some((m) => m.labelUids?.includes(label.uid)) && !appliedToAll.includes(label),
132
+ );
133
+
134
+
135
+ return (
136
+ <div className="border-b border-border">
137
+ <MoveToFolderDialog
138
+ open={movePrompt}
139
+ onClose={() => setMovePrompt(false)}
140
+ mailboxUid={mailboxUid}
141
+ folders={folders}
142
+ currentFolderUid={currentFolderUid}
143
+ count={selected.length}
144
+ onMove={onMoveTo}
145
+ onFolderCreated={onFolderCreated}
146
+ />
147
+ <div className="flex items-center gap-2 px-3 py-1.5 bg-surface-alt">
148
+ <span aria-live="polite" className="text-sm font-semibold text-text">
149
+ {selectedCount}
150
+ {totals ? ` ${totals.noun}${selectedCount === 1 ? "" : "s"}` : ""} selected
151
+ </span>
152
+ <button type="button" onClick={onSelectAll} disabled={allSelected || listedCount === 0} className={actionClassName()}>
153
+ Select all
154
+ </button>
155
+ <button type="button" onClick={onClearSelection} disabled={selectedCount === 0} className={actionClassName()}>
156
+ Clear
157
+ </button>
158
+ <button type="button" onClick={onCancel} className={`${actionClassName()} ml-auto`}>
159
+ Cancel
160
+ </button>
161
+ </div>
162
+ <div className="flex flex-wrap items-center gap-0.5 px-1.5 py-1">
163
+ <button type="button" onClick={() => onSetRead(true)} disabled={none || busy} className={actionClassName()} {...hint("Mark read", SHORTCUTS.mail.markRead)}>
164
+ Mark read
165
+ </button>
166
+ <button type="button" onClick={() => onSetRead(false)} disabled={none || busy} className={actionClassName()} {...hint("Mark unread", SHORTCUTS.mail.markUnread)}>
167
+ Mark unread
168
+ </button>
169
+ <button type="button" onClick={() => onSetFlagged(true)} disabled={none || busy} className={actionClassName()} {...hint("Flag", SHORTCUTS.mail.flag)}>
170
+ Flag
171
+ </button>
172
+ <button type="button" onClick={() => onSetFlagged(false)} disabled={none || busy} className={actionClassName()}>
173
+ Unflag
174
+ </button>
175
+ <button
176
+ type="button"
177
+ onClick={onArchive}
178
+ disabled={none || busy || !!archiveReason}
179
+ title={archiveReason}
180
+ className={actionClassName()}
181
+ >
182
+ Archive
183
+ </button>
184
+ <LabelMenuButton
185
+ aria-label="Apply label"
186
+ label="Apply label"
187
+ className="text-sm"
188
+ labels={labels}
189
+ mailboxUid={mailboxUid}
190
+ onLabelCreated={onLabelCreated}
191
+ applied={appliedToAll.map((label) => label.uid)}
192
+ partial={appliedToSome.map((label) => label.uid)}
193
+ onCommit={onApplyLabels}
194
+ busy={busy}
195
+ disabled={none || busy || !!labelsDisabledReason}
196
+ title={labelsDisabledReason}
197
+ note={
198
+ selected.length === 1
199
+ ? "Ticked labels are applied, unticked ones removed."
200
+ : "Ticked labels are applied to every selected message and unticked ones removed from all of them; a dash means only some have that label, and leaving it alone keeps it that way."
201
+ }
202
+ emptyNote="This mailbox has no labels yet."
203
+ commit={{ label: "Apply" }}
204
+ clear={{ label: "Remove all labels" }}
205
+ />
206
+ <button
207
+ type="button"
208
+ onClick={() => setMovePrompt(true)}
209
+ disabled={none || busy || !!moveDisabledReason}
210
+ title={moveDisabledReason}
211
+ className={actionClassName()}
212
+ >
213
+ Move to
214
+ </button>
215
+ <button
216
+ type="button"
217
+ onClick={onReportJunk}
218
+ disabled={none || busy || !!junkReason}
219
+ title={junkReason}
220
+ className={actionClassName()}
221
+ >
222
+ Report junk
223
+ </button>
224
+ <button
225
+ type="button"
226
+ onClick={onDelete}
227
+ disabled={none || busy || !!deleteReason}
228
+ className={actionClassName()}
229
+ {...hint("Delete", SHORTCUTS.mail.delete, deleteReason)}
230
+ >
231
+ Delete
232
+ </button>
233
+ </div>
234
+ </div>
235
+ );
236
+ }