@rapidmx/web-client 0.10.0 → 0.12.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 (324) hide show
  1. package/README.md +183 -2
  2. package/apps/admin/_layout.tsx +8 -2
  3. package/apps/admin/index.tsx +7 -1
  4. package/apps/admin/ingest-queue/index.tsx +2 -1
  5. package/apps/admin/mailboxes/[uid].tsx +23 -10
  6. package/apps/admin/mailboxes/new/index.tsx +3 -3
  7. package/apps/admin/quarantine/index.tsx +2 -1
  8. package/apps/admin/signing-certificates/index.tsx +343 -0
  9. package/apps/escrow/_layout.tsx +8 -2
  10. package/apps/shared/appearance/AppearanceForm.tsx +392 -0
  11. package/apps/shared/appearance/AppearanceHead.tsx +49 -0
  12. package/apps/shared/appearance/AppearanceProvider.tsx +470 -0
  13. package/apps/shared/appearance/ColorField.tsx +107 -0
  14. package/apps/shared/appearance/appearanceCache.ts +106 -0
  15. package/apps/shared/appearance/appearanceContext.ts +77 -0
  16. package/apps/shared/appearance/bootScript.ts +35 -0
  17. package/apps/shared/appearance/color.ts +169 -0
  18. package/apps/shared/appearance/photo.ts +88 -0
  19. package/apps/shared/appearance/resolvedTheme.ts +67 -0
  20. package/apps/shared/appearance/theme.ts +355 -0
  21. package/apps/shared/components/admin/escrowScopes/EscrowScopeKeyAndHoldersFields.tsx +4 -4
  22. package/apps/shared/components/admin/layout/AdminShell.tsx +22 -10
  23. package/apps/shared/components/admin/mailboxes/ShareAccessCard.tsx +107 -60
  24. package/apps/shared/components/admin/settings/BrandingForm.tsx +24 -0
  25. package/apps/shared/components/admin/settings/DomainDnsSetup.tsx +60 -14
  26. package/apps/shared/components/admin/settings/MailboxCreateForm.tsx +65 -16
  27. package/apps/shared/components/admin/settings/PluginsManager.tsx +228 -25
  28. package/apps/shared/components/admin/setup/SetupWizard.tsx +2 -1
  29. package/apps/shared/components/calendar/CalendarListSidebar.tsx +4 -5
  30. package/apps/shared/components/contacts/ContactForm.tsx +11 -5
  31. package/apps/shared/components/contacts/ContactsSidebar.tsx +5 -3
  32. package/apps/shared/components/contacts/ContactsToolbar.tsx +25 -52
  33. package/apps/shared/components/contacts/layout/ContactsShell.tsx +10 -5
  34. package/apps/shared/components/escrow/layout/EscrowShell.tsx +13 -6
  35. package/apps/shared/components/layout/AppShell.tsx +98 -32
  36. package/apps/shared/components/layout/BrandingChrome.tsx +200 -13
  37. package/apps/shared/components/layout/RailIcon.tsx +100 -0
  38. package/apps/shared/components/layout/ResponsiveToolbar.tsx +315 -0
  39. package/apps/shared/components/layout/ThemeSwitch.tsx +84 -0
  40. package/apps/shared/components/layout/UserMenu.tsx +75 -6
  41. package/apps/shared/components/mail/ConversationList.tsx +4 -2
  42. package/apps/shared/components/mail/ConversationThreadPane.tsx +487 -475
  43. package/apps/shared/components/mail/LazyReadingPane.tsx +14 -16
  44. package/apps/shared/components/mail/MailSelectionBar.tsx +2 -10
  45. package/apps/shared/components/mail/MessageDetailPane.tsx +366 -287
  46. package/apps/shared/components/mail/OutboxBadge.tsx +44 -0
  47. package/apps/shared/components/mail/OutboxRowStatus.tsx +31 -0
  48. package/apps/shared/components/mail/compose/ComposeContext.tsx +35 -2
  49. package/apps/shared/components/mail/compose/ComposeWindow.tsx +239 -437
  50. package/apps/shared/components/mail/compose/encryptionRequirement.ts +86 -0
  51. package/apps/shared/components/mail/layout/MailShell.tsx +39 -25
  52. package/apps/shared/components/mail/reading/EncryptedBody.tsx +65 -0
  53. package/apps/shared/components/mail/reading/EncryptedPreview.tsx +35 -0
  54. package/apps/shared/components/mail/reading/MessageBody.tsx +240 -0
  55. package/apps/shared/components/mail/reading/MessageCard.tsx +174 -0
  56. package/apps/shared/components/mail/reading/bodyContent.ts +100 -0
  57. package/apps/shared/components/mail/reading/bodyHtml.ts +298 -0
  58. package/apps/shared/components/mail/reading/color.ts +245 -0
  59. package/apps/shared/components/mail/reading/frameControl.ts +142 -0
  60. package/apps/shared/components/mail/reading/frameDocument.ts +123 -0
  61. package/apps/shared/components/mail/reading/safeDocument.ts +24 -0
  62. package/apps/shared/components/mail/reading/themeAdaptation.ts +221 -0
  63. package/apps/shared/components/mail/reading/themeSurface.ts +90 -0
  64. package/apps/shared/components/mail/reading/viewOriginal.ts +38 -0
  65. package/apps/shared/components/settings/SigningCertificateCard.tsx +344 -0
  66. package/apps/shared/components/settings/layout/SettingsShell.tsx +1 -0
  67. package/apps/shared/components/sharing/PrincipalListField.tsx +82 -0
  68. package/apps/shared/components/sharing/PrincipalPicker.tsx +76 -0
  69. package/apps/shared/components/sharing/PrincipalResolver.tsx +164 -0
  70. package/apps/shared/components/tasks/TasksSidebar.tsx +5 -3
  71. package/apps/shared/components/tasks/layout/TasksShell.tsx +9 -5
  72. package/apps/shared/mail/folderCounts.ts +9 -3
  73. package/apps/shared/mail/folderTree.ts +143 -0
  74. package/apps/shared/mail/outbox/UnlockBridge.tsx +23 -0
  75. package/apps/shared/mail/outbox/composeBridge.ts +69 -0
  76. package/apps/shared/mail/outbox/outboxState.ts +88 -0
  77. package/apps/shared/mail/outbox/pendingSends.ts +146 -0
  78. package/apps/shared/mail/outbox/sendDecision.ts +157 -0
  79. package/apps/shared/mail/outbox/sendJob.ts +427 -0
  80. package/apps/shared/mail/outbox/sendOutcomes.ts +146 -0
  81. package/apps/shared/mail/outbox/sendState.ts +35 -0
  82. package/apps/shared/mail/outbox/useOutboxStatus.ts +61 -0
  83. package/apps/shared/mail/useMailConnection.ts +81 -28
  84. package/apps/shared/mail/useMailLiveUpdates.ts +55 -10
  85. package/apps/shared/mail/useNewMailNotifications.ts +47 -32
  86. package/apps/shared/navigation/AppRouter.tsx +2 -2
  87. package/apps/shared/notifications/NotificationCenter.tsx +215 -0
  88. package/apps/shared/notifications/NotificationHistoryDialog.tsx +90 -0
  89. package/apps/shared/notifications/apiErrors.ts +98 -0
  90. package/apps/shared/notifications/headerOffset.ts +35 -0
  91. package/apps/shared/notifications/pushStatus.ts +56 -0
  92. package/apps/shared/notifications/store.ts +549 -0
  93. package/apps/shared/notifications/systemErrors.ts +63 -0
  94. package/apps/shared/notifications/useNotifications.ts +41 -0
  95. package/apps/shared/signing/enrollmentStorage.ts +33 -0
  96. package/apps/shared/signing/enrollmentTracker.ts +385 -0
  97. package/apps/shared/signing/enrollmentView.ts +251 -0
  98. package/apps/shared/signing/signingInfo.ts +58 -0
  99. package/apps/shared/signing/useNow.ts +19 -0
  100. package/apps/shared/signing/useSigningEnrollmentWatcher.ts +90 -0
  101. package/apps/shared/styles/app.css +80 -0
  102. package/apps/www/_layout.tsx +8 -2
  103. package/apps/www/_routes.ts +1 -0
  104. package/apps/www/calendar/index.tsx +9 -14
  105. package/apps/www/contacts/[uid].tsx +5 -8
  106. package/apps/www/contacts/index.tsx +587 -584
  107. package/apps/www/index.tsx +38 -27
  108. package/apps/www/messages/[uid].tsx +3 -1
  109. package/apps/www/settings/appearance/index.tsx +21 -0
  110. package/apps/www/settings/auto-reply/index.tsx +3 -7
  111. package/apps/www/settings/encryption/index.tsx +151 -116
  112. package/apps/www/settings/filters/[uid].tsx +3 -1
  113. package/apps/www/settings/filters/new/index.tsx +3 -1
  114. package/apps/www/settings/privacy/index.tsx +3 -8
  115. package/apps/www/settings/read-receipts/index.tsx +3 -7
  116. package/apps/www/settings/sharing/index.tsx +44 -65
  117. package/apps/www/settings/signatures/[uid].tsx +3 -1
  118. package/apps/www/settings/signatures/new/index.tsx +3 -2
  119. package/apps/www/tasks/index.tsx +11 -16
  120. package/dist/apps/admin/_layout.d.ts +5 -1
  121. package/dist/apps/admin/_layout.js +3 -2
  122. package/dist/apps/admin/index.js +3 -2
  123. package/dist/apps/admin/ingest-queue/index.js +2 -1
  124. package/dist/apps/admin/mailboxes/[uid].js +9 -6
  125. package/dist/apps/admin/mailboxes/new/index.js +1 -1
  126. package/dist/apps/admin/quarantine/index.js +2 -1
  127. package/dist/apps/admin/signing-certificates/index.d.ts +3 -0
  128. package/dist/apps/admin/signing-certificates/index.js +161 -0
  129. package/dist/apps/escrow/_layout.d.ts +5 -1
  130. package/dist/apps/escrow/_layout.js +3 -2
  131. package/dist/apps/shared/appearance/AppearanceForm.d.ts +7 -0
  132. package/dist/apps/shared/appearance/AppearanceForm.js +131 -0
  133. package/dist/apps/shared/appearance/AppearanceHead.d.ts +15 -0
  134. package/dist/apps/shared/appearance/AppearanceHead.js +31 -0
  135. package/dist/apps/shared/appearance/AppearanceProvider.d.ts +32 -0
  136. package/dist/apps/shared/appearance/AppearanceProvider.js +390 -0
  137. package/dist/apps/shared/appearance/ColorField.d.ts +22 -0
  138. package/dist/apps/shared/appearance/ColorField.js +40 -0
  139. package/dist/apps/shared/appearance/appearanceCache.d.ts +45 -0
  140. package/dist/apps/shared/appearance/appearanceCache.js +80 -0
  141. package/dist/apps/shared/appearance/appearanceContext.d.ts +45 -0
  142. package/dist/apps/shared/appearance/appearanceContext.js +29 -0
  143. package/dist/apps/shared/appearance/bootScript.d.ts +16 -0
  144. package/dist/apps/shared/appearance/bootScript.js +33 -0
  145. package/dist/apps/shared/appearance/color.d.ts +65 -0
  146. package/dist/apps/shared/appearance/color.js +132 -0
  147. package/dist/apps/shared/appearance/photo.d.ts +17 -0
  148. package/dist/apps/shared/appearance/photo.js +79 -0
  149. package/dist/apps/shared/appearance/resolvedTheme.d.ts +21 -0
  150. package/dist/apps/shared/appearance/resolvedTheme.js +55 -0
  151. package/dist/apps/shared/appearance/theme.d.ts +111 -0
  152. package/dist/apps/shared/appearance/theme.js +251 -0
  153. package/dist/apps/shared/components/admin/escrowScopes/EscrowScopeKeyAndHoldersFields.js +3 -2
  154. package/dist/apps/shared/components/admin/layout/AdminShell.d.ts +1 -1
  155. package/dist/apps/shared/components/admin/layout/AdminShell.js +16 -6
  156. package/dist/apps/shared/components/admin/mailboxes/ShareAccessCard.d.ts +10 -5
  157. package/dist/apps/shared/components/admin/mailboxes/ShareAccessCard.js +49 -34
  158. package/dist/apps/shared/components/admin/settings/BrandingForm.d.ts +2 -0
  159. package/dist/apps/shared/components/admin/settings/BrandingForm.js +7 -1
  160. package/dist/apps/shared/components/admin/settings/DomainDnsSetup.js +25 -5
  161. package/dist/apps/shared/components/admin/settings/MailboxCreateForm.js +18 -7
  162. package/dist/apps/shared/components/admin/settings/PluginsManager.js +106 -20
  163. package/dist/apps/shared/components/admin/setup/SetupWizard.js +2 -1
  164. package/dist/apps/shared/components/calendar/CalendarListSidebar.js +8 -8
  165. package/dist/apps/shared/components/contacts/ContactForm.js +1 -1
  166. package/dist/apps/shared/components/contacts/ContactsSidebar.js +4 -2
  167. package/dist/apps/shared/components/contacts/ContactsToolbar.d.ts +3 -1
  168. package/dist/apps/shared/components/contacts/ContactsToolbar.js +24 -9
  169. package/dist/apps/shared/components/contacts/layout/ContactsShell.js +4 -1
  170. package/dist/apps/shared/components/escrow/layout/EscrowShell.js +7 -4
  171. package/dist/apps/shared/components/layout/AppShell.d.ts +6 -1
  172. package/dist/apps/shared/components/layout/AppShell.js +59 -13
  173. package/dist/apps/shared/components/layout/BrandingChrome.d.ts +69 -10
  174. package/dist/apps/shared/components/layout/BrandingChrome.js +140 -12
  175. package/dist/apps/shared/components/layout/RailIcon.d.ts +21 -0
  176. package/dist/apps/shared/components/layout/RailIcon.js +85 -0
  177. package/dist/apps/shared/components/layout/ResponsiveToolbar.d.ts +55 -0
  178. package/dist/apps/shared/components/layout/ResponsiveToolbar.js +199 -0
  179. package/dist/apps/shared/components/layout/ThemeSwitch.d.ts +9 -0
  180. package/dist/apps/shared/components/layout/ThemeSwitch.js +54 -0
  181. package/dist/apps/shared/components/layout/UserMenu.d.ts +7 -1
  182. package/dist/apps/shared/components/layout/UserMenu.js +41 -7
  183. package/dist/apps/shared/components/mail/ConversationList.js +3 -2
  184. package/dist/apps/shared/components/mail/ConversationThreadPane.d.ts +2 -1
  185. package/dist/apps/shared/components/mail/ConversationThreadPane.js +42 -20
  186. package/dist/apps/shared/components/mail/LazyReadingPane.js +9 -8
  187. package/dist/apps/shared/components/mail/MailSelectionBar.d.ts +3 -4
  188. package/dist/apps/shared/components/mail/MailSelectionBar.js +2 -3
  189. package/dist/apps/shared/components/mail/MessageDetailPane.d.ts +18 -7
  190. package/dist/apps/shared/components/mail/MessageDetailPane.js +86 -41
  191. package/dist/apps/shared/components/mail/OutboxBadge.d.ts +17 -0
  192. package/dist/apps/shared/components/mail/OutboxBadge.js +18 -0
  193. package/dist/apps/shared/components/mail/OutboxRowStatus.d.ts +10 -0
  194. package/dist/apps/shared/components/mail/OutboxRowStatus.js +19 -0
  195. package/dist/apps/shared/components/mail/compose/ComposeContext.d.ts +8 -0
  196. package/dist/apps/shared/components/mail/compose/ComposeContext.js +28 -3
  197. package/dist/apps/shared/components/mail/compose/ComposeWindow.d.ts +2 -1
  198. package/dist/apps/shared/components/mail/compose/ComposeWindow.js +229 -328
  199. package/dist/apps/shared/components/mail/compose/encryptionRequirement.d.ts +49 -0
  200. package/dist/apps/shared/components/mail/compose/encryptionRequirement.js +35 -0
  201. package/dist/apps/shared/components/mail/layout/MailShell.d.ts +2 -0
  202. package/dist/apps/shared/components/mail/layout/MailShell.js +20 -14
  203. package/dist/apps/shared/components/mail/reading/EncryptedBody.d.ts +21 -0
  204. package/dist/apps/shared/components/mail/reading/EncryptedBody.js +22 -0
  205. package/dist/apps/shared/components/mail/reading/EncryptedPreview.d.ts +18 -0
  206. package/dist/apps/shared/components/mail/reading/EncryptedPreview.js +22 -0
  207. package/dist/apps/shared/components/mail/reading/MessageBody.d.ts +32 -0
  208. package/dist/apps/shared/components/mail/reading/MessageBody.js +136 -0
  209. package/dist/apps/shared/components/mail/reading/MessageCard.d.ts +62 -0
  210. package/dist/apps/shared/components/mail/reading/MessageCard.js +58 -0
  211. package/dist/apps/shared/components/mail/reading/bodyContent.d.ts +38 -0
  212. package/dist/apps/shared/components/mail/reading/bodyContent.js +84 -0
  213. package/dist/apps/shared/components/mail/reading/bodyHtml.d.ts +47 -0
  214. package/dist/apps/shared/components/mail/reading/bodyHtml.js +267 -0
  215. package/dist/apps/shared/components/mail/reading/color.d.ts +63 -0
  216. package/dist/apps/shared/components/mail/reading/color.js +201 -0
  217. package/dist/apps/shared/components/mail/reading/frameControl.d.ts +33 -0
  218. package/dist/apps/shared/components/mail/reading/frameControl.js +120 -0
  219. package/dist/apps/shared/components/mail/reading/frameDocument.d.ts +52 -0
  220. package/dist/apps/shared/components/mail/reading/frameDocument.js +98 -0
  221. package/dist/apps/shared/components/mail/reading/safeDocument.d.ts +3 -0
  222. package/dist/apps/shared/components/mail/reading/safeDocument.js +12 -0
  223. package/dist/apps/shared/components/mail/reading/themeAdaptation.d.ts +56 -0
  224. package/dist/apps/shared/components/mail/reading/themeAdaptation.js +144 -0
  225. package/dist/apps/shared/components/mail/reading/themeSurface.d.ts +17 -0
  226. package/dist/apps/shared/components/mail/reading/themeSurface.js +83 -0
  227. package/dist/apps/shared/components/mail/reading/viewOriginal.d.ts +9 -0
  228. package/dist/apps/shared/components/mail/reading/viewOriginal.js +32 -0
  229. package/dist/apps/shared/components/settings/SigningCertificateCard.d.ts +32 -0
  230. package/dist/apps/shared/components/settings/SigningCertificateCard.js +98 -0
  231. package/dist/apps/shared/components/settings/layout/SettingsShell.js +1 -0
  232. package/dist/apps/shared/components/sharing/PrincipalListField.d.ts +24 -0
  233. package/dist/apps/shared/components/sharing/PrincipalListField.js +23 -0
  234. package/dist/apps/shared/components/sharing/PrincipalPicker.d.ts +28 -0
  235. package/dist/apps/shared/components/sharing/PrincipalPicker.js +24 -0
  236. package/dist/apps/shared/components/sharing/PrincipalResolver.d.ts +44 -0
  237. package/dist/apps/shared/components/sharing/PrincipalResolver.js +92 -0
  238. package/dist/apps/shared/components/tasks/TasksSidebar.js +4 -2
  239. package/dist/apps/shared/components/tasks/layout/TasksShell.js +3 -1
  240. package/dist/apps/shared/mail/folderCounts.d.ts +1 -1
  241. package/dist/apps/shared/mail/folderCounts.js +9 -3
  242. package/dist/apps/shared/mail/folderTree.d.ts +55 -0
  243. package/dist/apps/shared/mail/folderTree.js +116 -0
  244. package/dist/apps/shared/mail/outbox/UnlockBridge.d.ts +5 -0
  245. package/dist/apps/shared/mail/outbox/UnlockBridge.js +18 -0
  246. package/dist/apps/shared/mail/outbox/composeBridge.d.ts +34 -0
  247. package/dist/apps/shared/mail/outbox/composeBridge.js +32 -0
  248. package/dist/apps/shared/mail/outbox/outboxState.d.ts +41 -0
  249. package/dist/apps/shared/mail/outbox/outboxState.js +42 -0
  250. package/dist/apps/shared/mail/outbox/pendingSends.d.ts +39 -0
  251. package/dist/apps/shared/mail/outbox/pendingSends.js +109 -0
  252. package/dist/apps/shared/mail/outbox/sendDecision.d.ts +80 -0
  253. package/dist/apps/shared/mail/outbox/sendDecision.js +94 -0
  254. package/dist/apps/shared/mail/outbox/sendJob.d.ts +68 -0
  255. package/dist/apps/shared/mail/outbox/sendJob.js +319 -0
  256. package/dist/apps/shared/mail/outbox/sendOutcomes.d.ts +3 -0
  257. package/dist/apps/shared/mail/outbox/sendOutcomes.js +141 -0
  258. package/dist/apps/shared/mail/outbox/sendState.d.ts +25 -0
  259. package/dist/apps/shared/mail/outbox/sendState.js +8 -0
  260. package/dist/apps/shared/mail/outbox/useOutboxStatus.d.ts +11 -0
  261. package/dist/apps/shared/mail/outbox/useOutboxStatus.js +49 -0
  262. package/dist/apps/shared/mail/useMailConnection.d.ts +9 -8
  263. package/dist/apps/shared/mail/useMailConnection.js +64 -22
  264. package/dist/apps/shared/mail/useMailLiveUpdates.d.ts +17 -4
  265. package/dist/apps/shared/mail/useMailLiveUpdates.js +36 -10
  266. package/dist/apps/shared/mail/useNewMailNotifications.d.ts +4 -10
  267. package/dist/apps/shared/mail/useNewMailNotifications.js +43 -23
  268. package/dist/apps/shared/navigation/AppRouter.js +2 -2
  269. package/dist/apps/shared/notifications/NotificationCenter.d.ts +19 -0
  270. package/dist/apps/shared/notifications/NotificationCenter.js +90 -0
  271. package/dist/apps/shared/notifications/NotificationHistoryDialog.d.ts +10 -0
  272. package/dist/apps/shared/notifications/NotificationHistoryDialog.js +36 -0
  273. package/dist/apps/shared/notifications/apiErrors.d.ts +19 -0
  274. package/dist/apps/shared/notifications/apiErrors.js +86 -0
  275. package/dist/apps/shared/notifications/headerOffset.d.ts +8 -0
  276. package/dist/apps/shared/notifications/headerOffset.js +33 -0
  277. package/dist/apps/shared/notifications/pushStatus.d.ts +9 -0
  278. package/dist/apps/shared/notifications/pushStatus.js +54 -0
  279. package/dist/apps/shared/notifications/store.d.ts +136 -0
  280. package/dist/apps/shared/notifications/store.js +416 -0
  281. package/dist/apps/shared/notifications/systemErrors.d.ts +9 -0
  282. package/dist/apps/shared/notifications/systemErrors.js +58 -0
  283. package/dist/apps/shared/notifications/useNotifications.d.ts +17 -0
  284. package/dist/apps/shared/notifications/useNotifications.js +18 -0
  285. package/dist/apps/shared/signing/enrollmentStorage.d.ts +10 -0
  286. package/dist/apps/shared/signing/enrollmentStorage.js +33 -0
  287. package/dist/apps/shared/signing/enrollmentTracker.d.ts +73 -0
  288. package/dist/apps/shared/signing/enrollmentTracker.js +307 -0
  289. package/dist/apps/shared/signing/enrollmentView.d.ts +57 -0
  290. package/dist/apps/shared/signing/enrollmentView.js +214 -0
  291. package/dist/apps/shared/signing/signingInfo.d.ts +11 -0
  292. package/dist/apps/shared/signing/signingInfo.js +48 -0
  293. package/dist/apps/shared/signing/useNow.d.ts +2 -0
  294. package/dist/apps/shared/signing/useNow.js +18 -0
  295. package/dist/apps/shared/signing/useSigningEnrollmentWatcher.d.ts +16 -0
  296. package/dist/apps/shared/signing/useSigningEnrollmentWatcher.js +87 -0
  297. package/dist/apps/shared/styles/app.css +80 -0
  298. package/dist/apps/www/_layout.d.ts +5 -1
  299. package/dist/apps/www/_layout.js +3 -2
  300. package/dist/apps/www/_routes.js +1 -0
  301. package/dist/apps/www/calendar/index.js +3 -4
  302. package/dist/apps/www/contacts/[uid].js +5 -7
  303. package/dist/apps/www/contacts/index.js +14 -21
  304. package/dist/apps/www/index.js +37 -19
  305. package/dist/apps/www/messages/[uid].js +3 -1
  306. package/dist/apps/www/settings/appearance/index.d.ts +4 -0
  307. package/dist/apps/www/settings/appearance/index.js +13 -0
  308. package/dist/apps/www/settings/auto-reply/index.js +3 -6
  309. package/dist/apps/www/settings/encryption/index.js +103 -95
  310. package/dist/apps/www/settings/filters/[uid].js +3 -1
  311. package/dist/apps/www/settings/filters/new/index.js +3 -1
  312. package/dist/apps/www/settings/privacy/index.js +5 -8
  313. package/dist/apps/www/settings/read-receipts/index.js +3 -6
  314. package/dist/apps/www/settings/sharing/index.js +19 -33
  315. package/dist/apps/www/settings/signatures/[uid].js +3 -1
  316. package/dist/apps/www/settings/signatures/new/index.js +3 -2
  317. package/dist/apps/www/tasks/index.js +8 -14
  318. package/package.json +2 -2
  319. package/apps/shared/components/mail/NewMailToasts.tsx +0 -141
  320. package/apps/shared/components/mail/compose/SendFailureAlert.tsx +0 -48
  321. package/dist/apps/shared/components/mail/NewMailToasts.d.ts +0 -19
  322. package/dist/apps/shared/components/mail/NewMailToasts.js +0 -55
  323. package/dist/apps/shared/components/mail/compose/SendFailureAlert.d.ts +0 -14
  324. package/dist/apps/shared/components/mail/compose/SendFailureAlert.js +0 -11
@@ -20,6 +20,7 @@ import {
20
20
  createFolder,
21
21
  getMessage,
22
22
  getMessageRawContent,
23
+ listFolders,
23
24
  listMessages,
24
25
  moveMessages,
25
26
  setMessagesFlagged,
@@ -46,6 +47,7 @@ import MailShell, {
46
47
  useMailShell,
47
48
  } from "../shared/components/mail/layout/MailShell.js";
48
49
  import MailAddress from "../shared/components/mail/MailAddress.js";
50
+ import OutboxRowStatus from "../shared/components/mail/OutboxRowStatus.js";
49
51
  import { mergeFirstPage } from "../shared/mail/mergeFirstPage.js";
50
52
  import { listSnapshotKey, readListSnapshot, saveListScroll, writeListSnapshot } from "../shared/mail/listSnapshots.js";
51
53
  import { setReadStateMany } from "../shared/mail/messageReadState.js";
@@ -53,6 +55,7 @@ import { useMarkMessageRead } from "../shared/mail/useMarkMessageRead.js";
53
55
  import { ROW_FOCUS_CLASS, UnreadBar, UnreadLabel, dateClass, isUnread, rowClass, senderClass, subjectClass } from "../shared/components/mail/unreadStyle.js";
54
56
  import { LazyConversationThreadPane, LazyMessageDetailPane, prefetchReadingPane } from "../shared/components/mail/LazyReadingPane.js";
55
57
  import ConversationList from "../shared/components/mail/ConversationList.js";
58
+ import { EncryptedPreview } from "../shared/components/mail/reading/EncryptedPreview.js";
56
59
  import MailListToolbar from "../shared/components/mail/MailListToolbar.js";
57
60
  import MailSelectionBar from "../shared/components/mail/MailSelectionBar.js";
58
61
  import {
@@ -70,6 +73,7 @@ import { useUnlockPrompt } from "../shared/components/layout/UnlockPromptProvide
70
73
  import { SHORTCUTS } from "../shared/keyboard/keymap.js";
71
74
  import { isActivatable } from "../shared/keyboard/targets.js";
72
75
  import { useShortcut } from "../shared/keyboard/useShortcut.js";
76
+ import { notifyApiError } from "../shared/notifications/apiErrors.js";
73
77
 
74
78
  const MESSAGE_PAGE_SIZE = 50;
75
79
  const SEARCH_DEBOUNCE_MS = 300;
@@ -461,7 +465,7 @@ function InboxPage(props: MailShellProps) {
461
465
  }
462
466
 
463
467
  function InboxContent({ userUid }: { userUid?: string }) {
464
- const { folderUid, mailboxUid, mailboxes, mailboxFolders, aggregateFolderType, onFolderCreated, live, trackMessageChange } = useMailShell();
468
+ const { folderUid, mailboxUid, mailboxes, mailboxFolders, aggregateFolderType, onFolderCreated, noteFolderUids, live, trackMessageChange } = useMailShell();
465
469
  const isMobile = useIsMobile();
466
470
  const navigate = useNavigate();
467
471
  const { requestUnlock } = useUnlockPrompt();
@@ -503,7 +507,6 @@ function InboxContent({ userUid }: { userUid?: string }) {
503
507
  // or it would act on a selection that is still arriving.
504
508
  const [resolvingSelection, setResolvingSelection] = useState(0);
505
509
  const [bulkBusy, setBulkBusy] = useState(false);
506
- const [bulkError, setBulkError] = useState<string | null>(null);
507
510
  // Bumped to force the list effect below to re-run - a bulk update is deliberately neither atomic nor
508
511
  // all-or-nothing (see `bulkUpdateMessages()`), so a rejection means refetching rather than guessing
509
512
  // which half of the selection actually landed.
@@ -1120,10 +1123,18 @@ function InboxContent({ userUid }: { userUid?: string }) {
1120
1123
  unlockRefresh,
1121
1124
  searchAllMail,
1122
1125
  aggregateFolderType,
1123
- mailboxFolders,
1126
+ // Only a merged view is built from the folder tree; for a single folder a folder appearing in the sidebar (the Outbox, Sent Items) must not reload
1127
+ // the list on screen and forget its selection.
1128
+ aggregateFolderType ? mailboxFolders : null,
1124
1129
  activeMailboxUid,
1125
1130
  ]);
1126
1131
 
1132
+ // Which folders the messages on screen live in: one the sidebar does not know (the Outbox and Sent Items are made by the server on first use) is looked for -
1133
+ // its mailbox's folders are listed again, once - so it appears without a reload. A conversation names every folder it has a message in.
1134
+ useEffect(() => {
1135
+ noteFolderUids([...messages.map((message) => message.folderUid), ...conversations.flatMap((conversation) => conversation.folderUids)]);
1136
+ }, [messages, conversations, noteFolderUids]);
1137
+
1127
1138
  // New mail without a reload. `live` is bumped by a push event, a reconnect, the safety-net poll or the tab coming back (see
1128
1139
  // `useMailLiveUpdates()`); this then quietly refetches the first page of whatever is listed and folds it in - unlike the
1129
1140
  // effect above it resets nothing: not the selection, the open thread, select mode, the scroll position or the rows
@@ -1454,7 +1465,6 @@ function InboxContent({ userUid }: { userUid?: string }) {
1454
1465
  setSelectMode(false);
1455
1466
  setSelectedUids(new Set());
1456
1467
  setSelectedConversationIds(new Set());
1457
- setBulkError(null);
1458
1468
  }
1459
1469
 
1460
1470
  function toggleSelected(uid: string) {
@@ -1471,7 +1481,7 @@ function InboxContent({ userUid }: { userUid?: string }) {
1471
1481
 
1472
1482
  /** Loads (once) the messages behind each of `ids`, so a ticked conversation resolves to the messages
1473
1483
  * every bulk action below acts on. If any of them fails to load, none of that batch stays ticked and
1474
- * the bar says why - better than acting on the part of a selection that happened to arrive. */
1484
+ * a pop-up says why - better than acting on the part of a selection that happened to arrive. */
1475
1485
  async function resolveConversations(ids: string[]) {
1476
1486
  const missing = ids.filter((id) => !conversationMessagesById[id]);
1477
1487
  if (missing.length === 0) {
@@ -1484,9 +1494,7 @@ function InboxContent({ userUid }: { userUid?: string }) {
1484
1494
  );
1485
1495
  setConversationMessagesById((prev) => ({ ...prev, ...Object.fromEntries(loaded) }));
1486
1496
  } catch (err) {
1487
- setBulkError(
1488
- err instanceof ApiRequestError ? err.message : "Could not load the messages in one of those conversations.",
1489
- );
1497
+ notifyApiError(err, "Couldn't load the messages in one of those conversations");
1490
1498
  setSelectedConversationIds((prev) => {
1491
1499
  const next = new Set(prev);
1492
1500
  for (const id of missing) {
@@ -1528,7 +1536,8 @@ function InboxContent({ userUid }: { userUid?: string }) {
1528
1536
  *
1529
1537
  * A bulk update is applied element by element server-side and stops at its first rejection, so a
1530
1538
  * failure leaves an unknown prefix of the selection already changed (see `bulkUpdateMessages()`) -
1531
- * which is why a failure reloads the list rather than trying to reconcile it, and says so.
1539
+ * which is why a failure reloads the list rather than trying to reconcile it, and says so ("all of those messages" in the pop-up's
1540
+ * title: some may have changed).
1532
1541
  *
1533
1542
  * `chosen` is the selection bar's ticked messages unless the caller (a keyboard shortcut acting on the one open message or conversation)
1534
1543
  * names its own. Resolves whether it succeeded.
@@ -1539,7 +1548,6 @@ function InboxContent({ userUid }: { userUid?: string }) {
1539
1548
  chosen: Message[] = selectedMessages,
1540
1549
  ): Promise<boolean> {
1541
1550
  setBulkBusy(true);
1542
- setBulkError(null);
1543
1551
  try {
1544
1552
  const updated = await action(chosen);
1545
1553
  if (removesRows) {
@@ -1569,9 +1577,7 @@ function InboxContent({ userUid }: { userUid?: string }) {
1569
1577
  setSelectedUids(new Set());
1570
1578
  return true;
1571
1579
  } catch (err) {
1572
- setBulkError(
1573
- `${err instanceof ApiRequestError ? err.message : "Those messages couldn't all be updated."} Some of them may already have changed, so the list has been reloaded.`,
1574
- );
1580
+ notifyApiError(err, chosen.length === 1 ? "Couldn't update the message" : "Couldn't update all of those messages");
1575
1581
  setSelectedUids(new Set());
1576
1582
  setSelectedConversationIds(new Set());
1577
1583
  setConversationMessagesById({});
@@ -1596,12 +1602,13 @@ function InboxContent({ userUid }: { userUid?: string }) {
1596
1602
  }
1597
1603
 
1598
1604
  /**
1599
- * This mailbox's folder of `type`, created on demand. A mailbox is provisioned with only the folders it
1600
- * has needed so far, so Deleted Items and Junk may genuinely not exist the first time a selection is
1601
- * deleted or reported - and unlike Archive, neither has a server-side lazy-create route to go through.
1605
+ * This mailbox's folder of `type`. The server makes every well-known folder itself (when the mailbox is made, and again when the folders are listed
1606
+ * if one is missing), so a folder the page's tree lacks is asked for - the tree may simply be out of date - and used, never created a second time: a
1607
+ * duplicate of a well-known type is invisible to the server (it answers with the oldest) but would be a second row in the sidebar. Only a server that
1608
+ * really has none (an older one, which makes Deleted Items and Junk on first use) is asked to create it.
1602
1609
  *
1603
- * A folder created here isn't in `mailboxFolders` (the shell fetched that once), so it's remembered per
1604
- * mailbox and type until the page reloads; otherwise a second Delete would create a second folder.
1610
+ * A folder found or created here may not be in `mailboxFolders` yet, so it is filed there and remembered per mailbox and type until the page
1611
+ * reloads; otherwise a second Delete would ask again.
1605
1612
  */
1606
1613
  async function resolveFolderOfType(type: Folder["type"], name: string): Promise<string> {
1607
1614
  const key = `${activeMailboxUid}:${type}`;
@@ -1609,6 +1616,12 @@ function InboxContent({ userUid }: { userUid?: string }) {
1609
1616
  if (known) {
1610
1617
  return known;
1611
1618
  }
1619
+ const listed = (await listFolders(activeMailboxUid)).find((f) => f.type === type);
1620
+ if (listed) {
1621
+ onFolderCreated(listed);
1622
+ lazyFoldersRef.current.set(key, listed.uid);
1623
+ return listed.uid;
1624
+ }
1612
1625
  const created = await createFolder({ mailboxUid: activeMailboxUid, name, type });
1613
1626
  lazyFoldersRef.current.set(key, created.uid);
1614
1627
  return created.uid;
@@ -1784,7 +1797,7 @@ function InboxContent({ userUid }: { userUid?: string }) {
1784
1797
  try {
1785
1798
  chosen = selectMode ? selectedMessages : inConversations ? await loadOpenConversation(openThread!.conversation) : [selected!];
1786
1799
  } catch (err) {
1787
- setBulkError(err instanceof ApiRequestError ? err.message : "Could not load the messages in that conversation.");
1800
+ notifyApiError(err, "Couldn't load the messages in that conversation");
1788
1801
  return;
1789
1802
  }
1790
1803
  chosen = chosen.filter(applies);
@@ -1934,7 +1947,6 @@ function InboxContent({ userUid }: { userUid?: string }) {
1934
1947
  onReportJunk={() => void moveSelectionToType("junk", "Junk Email")}
1935
1948
  onDelete={() => void moveSelectionToType("deleted_items", "Deleted Items")}
1936
1949
  busy={bulkBusy || resolvingSelection > 0}
1937
- error={bulkError}
1938
1950
  />
1939
1951
  ) : (
1940
1952
  <MailListToolbar
@@ -2079,12 +2091,6 @@ function InboxContent({ userUid }: { userUid?: string }) {
2079
2091
  <Alert>{error}</Alert>
2080
2092
  </div>
2081
2093
  )}
2082
- {/* Select mode shows a bulk action's failure in its own bar; the keyboard's actions on the one open message need somewhere too. */}
2083
- {!selectMode && bulkError && (
2084
- <div className="p-4">
2085
- <Alert>{bulkError}</Alert>
2086
- </div>
2087
- )}
2088
2094
 
2089
2095
  {loading ? (
2090
2096
  // A skeleton of rows rather than a line of text: the list keeps its shape while a folder that was not shown a
@@ -2189,13 +2195,18 @@ function InboxContent({ userUid }: { userUid?: string }) {
2189
2195
  </div>
2190
2196
  <div className="flex items-center gap-2 text-xs text-text-muted font-normal">
2191
2197
  <span className="truncate">
2192
- {snippets[message.uid] || decryptedRows[message.uid]?.preview || message.bodyPreview}
2198
+ {snippets[message.uid] ||
2199
+ decryptedRows[message.uid]?.preview ||
2200
+ message.bodyPreview ||
2201
+ (message.encrypted ? <EncryptedPreview /> : null)}
2193
2202
  </span>
2194
2203
  {message.hasAttachments && <HiOutlinePaperClip size={12} aria-label="Has attachments" />}
2195
2204
  {message.flags.flagged && (
2196
2205
  <HiOutlineFlag size={12} aria-label="Flagged" className="text-danger" />
2197
2206
  )}
2198
2207
  </div>
2208
+ {/* What the server is doing with a message in Outbox: sending, retrying, or why it wasn't sent. */}
2209
+ {isOutbox && <OutboxRowStatus message={message} />}
2199
2210
  </>
2200
2211
  )}
2201
2212
  </button>
@@ -11,6 +11,7 @@ import { useMessageAttachments } from "@rapidmx/react-shared/mail/mailDetailHook
11
11
  import { useMarkMessageRead } from "../../shared/mail/useMarkMessageRead.js";
12
12
  import MailShell, { MailShellProps, useMailShell } from "../../shared/components/mail/layout/MailShell.js";
13
13
  import { LazyMessageDetailPane } from "../../shared/components/mail/LazyReadingPane.js";
14
+ import { ReadingPaneSkeleton } from "../../shared/components/mail/reading/MessageCard.js";
14
15
  import Alert from "@rapidmx/react-shared/components/feedback/Alert.js";
15
16
 
16
17
  /**
@@ -66,7 +67,8 @@ function MessageDetailContent({ uid }: { uid: string }) {
66
67
  useMarkMessageRead(message, setMessage);
67
68
 
68
69
  if (loading) {
69
- return <p className="p-8 text-sm text-text-muted">Loading&hellip;</p>;
70
+ // The pane's own frame - a header card and a message card - rather than a line of text: what is coming is known, only not yet its contents.
71
+ return <ReadingPaneSkeleton />;
70
72
  }
71
73
  if (error || !message) {
72
74
  return <Alert>{error ?? "Message not found."}</Alert>;
@@ -0,0 +1,21 @@
1
+ ///////////////////////////////////////////////////////////////////////////////
2
+ // Copyright (C) 2026 Jean-Philippe Steinmetz
3
+ // SPDX-License-Identifier: MPL-2.0
4
+ ///////////////////////////////////////////////////////////////////////////////
5
+ import { routedPage } from "../../_routedPage.js";
6
+ import React from "react";
7
+ import SettingsShell, { SettingsShellProps } from "../../../shared/components/settings/layout/SettingsShell.js";
8
+ import AppearanceForm from "../../../shared/appearance/AppearanceForm.js";
9
+
10
+ export type SettingsAppearancePageProps = Omit<SettingsShellProps, "active">;
11
+
12
+ /** Settings > Appearance: the colour scheme, theme colours and background. Not mailbox-scoped - it is the signed-in user's own. */
13
+ function SettingsAppearancePage(props: SettingsAppearancePageProps) {
14
+ return (
15
+ <SettingsShell {...props} active="appearance">
16
+ <AppearanceForm />
17
+ </SettingsShell>
18
+ );
19
+ }
20
+
21
+ export default routedPage("/settings/appearance", SettingsAppearancePage);
@@ -4,12 +4,11 @@
4
4
  ///////////////////////////////////////////////////////////////////////////////
5
5
  import { routedPage } from "../../_routedPage.js";
6
6
  import React, { FormEvent, useState } from "react";
7
- import { ApiRequestError } from "@rapidmx/react-shared/util/api.js";
8
7
  import { toDatetimeLocal } from "@rapidmx/react-shared/util/dateInput.js";
9
8
  import { updateMailbox } from "@rapidmx/react-shared/mail/mailApi.js";
10
9
  import SettingsShell, { SettingsShellProps, useSettingsShell } from "../../../shared/components/settings/layout/SettingsShell.js";
11
- import Alert from "@rapidmx/react-shared/components/feedback/Alert.js";
12
10
  import Button from "@rapidmx/react-shared/components/buttons/Button.js";
11
+ import { notifyApiError } from "../../../shared/notifications/apiErrors.js";
13
12
 
14
13
  const INPUT_CLASS =
15
14
  "w-full text-sm py-2 px-3 border border-border rounded-sm bg-surface text-text focus:outline-none focus:border-primary";
@@ -38,13 +37,11 @@ function AutoReplyContent() {
38
37
  // `SettingsShell`'s `mailboxes` is fetched once - every save bumps the server's version, so a second
39
38
  // save without a reload must send the version the previous save returned, not the stale original.
40
39
  const [version, setVersion] = useState(mailbox.version);
41
- const [error, setError] = useState<string | null>(null);
42
40
  const [saving, setSaving] = useState(false);
43
41
  const [saved, setSaved] = useState(false);
44
42
 
45
43
  async function handleSubmit(e: FormEvent) {
46
44
  e.preventDefault();
47
- setError(null);
48
45
  setSaved(false);
49
46
  setSaving(true);
50
47
  try {
@@ -60,7 +57,7 @@ function AutoReplyContent() {
60
57
  setVersion(updated.version);
61
58
  setSaved(true);
62
59
  } catch (err) {
63
- setError(err instanceof ApiRequestError ? err.message : "Could not save automatic reply settings.");
60
+ notifyApiError(err, "Couldn't save the automatic reply settings");
64
61
  } finally {
65
62
  setSaving(false);
66
63
  }
@@ -75,8 +72,7 @@ function AutoReplyContent() {
75
72
  calendar event with its own automatic reply enabled takes over for its own start/end window.
76
73
  </p>
77
74
 
78
- {error && <Alert>{error}</Alert>}
79
- {saved && !error && <div className="mb-4 text-sm text-success font-medium">Saved.</div>}
75
+ {saved && <div className="mb-4 text-sm text-success font-medium">Saved.</div>}
80
76
 
81
77
  <form onSubmit={handleSubmit} className="flex flex-col gap-4">
82
78
  <label className="flex items-center gap-2 text-sm font-medium">