@rapidmx/web-client 0.4.0 → 0.6.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 (320) hide show
  1. package/README.md +88 -0
  2. package/apps/admin/audit-log/index.tsx +35 -8
  3. package/apps/admin/data-requests/index.tsx +480 -485
  4. package/apps/admin/distribution-lists/[uid].tsx +19 -1
  5. package/apps/admin/escrow-scopes/[uid].tsx +348 -237
  6. package/apps/admin/escrow-scopes/new/index.tsx +8 -2
  7. package/apps/admin/index.tsx +19 -1
  8. package/apps/admin/ingest-queue/index.tsx +44 -5
  9. package/apps/admin/mailboxes/[uid].tsx +211 -184
  10. package/apps/admin/quarantine/index.tsx +46 -14
  11. package/apps/admin/transport-rules/[uid].tsx +30 -1
  12. package/apps/admin/transport-rules/_transportRuleConfig.tsx +38 -2
  13. package/apps/admin/transport-rules/index.tsx +24 -6
  14. package/apps/admin/transport-rules/new/index.tsx +30 -1
  15. package/apps/escrow/_layout.tsx +2 -3
  16. package/apps/escrow/audit-log/index.tsx +196 -168
  17. package/apps/escrow/matters/[uid].tsx +621 -521
  18. package/apps/shared/components/admin/escrowScopes/EscrowScopeKeyAndHoldersFields.tsx +22 -1
  19. package/apps/shared/components/admin/layout/AdminShell.tsx +28 -9
  20. package/apps/shared/components/admin/mailboxes/EscrowScopeCard.tsx +152 -0
  21. package/apps/shared/components/admin/mailboxes/ResourceSettingsCard.tsx +3 -3
  22. package/apps/shared/components/admin/mailboxes/ShareAccessCard.tsx +55 -11
  23. package/apps/shared/components/admin/settings/BrandingForm.tsx +15 -4
  24. package/apps/shared/components/admin/settings/DomainDnsSetup.tsx +18 -7
  25. package/apps/shared/components/admin/settings/EncryptionPolicyForm.tsx +10 -2
  26. package/apps/shared/components/admin/settings/MailboxCreateForm.tsx +6 -0
  27. package/apps/shared/components/admin/settings/MailboxPolicyForm.tsx +45 -12
  28. package/apps/shared/components/admin/settings/PluginsManager.tsx +1235 -595
  29. package/apps/shared/components/admin/settings/RetentionPolicyForm.tsx +174 -98
  30. package/apps/shared/components/admin/setup/EscrowSetupStep.tsx +49 -13
  31. package/apps/shared/components/admin/setup/SetupWizard.tsx +150 -34
  32. package/apps/shared/components/admin/signOut.ts +79 -0
  33. package/apps/shared/components/admin/usePagedList.tsx +129 -0
  34. package/apps/shared/components/calendar/EventModal.tsx +717 -549
  35. package/apps/shared/components/calendar/MonthView.tsx +173 -139
  36. package/apps/shared/components/calendar/RecurrenceEditor.tsx +222 -180
  37. package/apps/shared/components/calendar/SplitDayView.tsx +143 -137
  38. package/apps/shared/components/calendar/TimeGridView.tsx +244 -198
  39. package/apps/shared/components/calendar/allDay.ts +124 -0
  40. package/apps/shared/components/calendar/layout/CalendarShell.tsx +194 -192
  41. package/apps/shared/components/contacts/ContactDetailPane.tsx +100 -21
  42. package/apps/shared/components/contacts/ContactForm.tsx +377 -348
  43. package/apps/shared/components/contacts/ContactsSidebar.tsx +6 -2
  44. package/apps/shared/components/contacts/KeyChangeReview.tsx +192 -0
  45. package/apps/shared/components/contacts/contactKeys.ts +78 -0
  46. package/apps/shared/components/contacts/layout/ContactsShell.tsx +199 -197
  47. package/apps/shared/components/escrow/layout/EscrowShell.tsx +148 -134
  48. package/apps/shared/components/layout/AppShell.tsx +123 -33
  49. package/apps/shared/components/layout/BrandingChrome.tsx +48 -10
  50. package/apps/shared/components/layout/KeyEnrollmentGate.tsx +389 -298
  51. package/apps/shared/components/layout/MailboxProvisioning.tsx +19 -3
  52. package/apps/shared/components/layout/RecoveryCodeUnlock.tsx +350 -0
  53. package/apps/shared/components/layout/UnlockPromptProvider.tsx +257 -128
  54. package/apps/shared/components/mail/ConversationThreadPane.tsx +216 -181
  55. package/apps/shared/components/mail/MessageDetailPane.tsx +1318 -630
  56. package/apps/shared/components/mail/compose/ComposeContext.tsx +20 -15
  57. package/apps/shared/components/mail/compose/ComposeWindow.tsx +854 -132
  58. package/apps/shared/components/mail/compose/composeFlushRegistry.ts +60 -0
  59. package/apps/shared/components/mail/layout/MailShell.tsx +420 -408
  60. package/apps/shared/components/mail/pinnedSigners.ts +124 -0
  61. package/apps/shared/components/mail/verificationSeals.ts +125 -0
  62. package/apps/shared/components/mail/writableMailboxes.ts +101 -0
  63. package/apps/shared/components/rules/RuleBuilder.tsx +311 -276
  64. package/apps/shared/components/settings/layout/SettingsShell.tsx +23 -9
  65. package/apps/shared/components/tasks/layout/TasksShell.tsx +201 -199
  66. package/apps/shared/mail/listAllPages.ts +39 -0
  67. package/apps/shared/plugins/pluginNav.ts +73 -0
  68. package/apps/shared/search/LocalIndexLifecycle.tsx +64 -55
  69. package/apps/shared/search/localIndexBuilder.ts +481 -179
  70. package/apps/shared/search/localIndexRpcClient.ts +231 -29
  71. package/apps/shared/search/localIndexSchema.ts +15 -6
  72. package/apps/shared/search/localIndexStorage.ts +98 -0
  73. package/apps/shared/search/localIndexVFS.ts +32 -1
  74. package/apps/shared/search/localIndexWorker.ts +648 -186
  75. package/apps/www/calendar/index.tsx +438 -417
  76. package/apps/www/contacts/[uid].tsx +21 -2
  77. package/apps/www/contacts/index.tsx +116 -12
  78. package/apps/www/index.tsx +1314 -1041
  79. package/apps/www/messages/[uid].tsx +18 -6
  80. package/apps/www/settings/auto-reply/index.tsx +134 -129
  81. package/apps/www/settings/encryption/index.tsx +739 -216
  82. package/apps/www/settings/filters/[uid].tsx +171 -155
  83. package/apps/www/settings/filters/new/index.tsx +8 -1
  84. package/apps/www/settings/focused-inbox/index.tsx +150 -148
  85. package/apps/www/settings/privacy/index.tsx +494 -436
  86. package/apps/www/settings/read-receipts/index.tsx +148 -125
  87. package/apps/www/settings/sharing/index.tsx +17 -14
  88. package/apps/www/tasks/index.tsx +638 -579
  89. package/dist/apps/admin/_404.d.ts +2 -0
  90. package/dist/apps/admin/_500.d.ts +2 -0
  91. package/dist/apps/admin/_layout.d.ts +8 -0
  92. package/dist/apps/admin/audit-log/index.d.ts +11 -0
  93. package/dist/apps/admin/audit-log/index.js +38 -8
  94. package/dist/apps/admin/branding/index.d.ts +3 -0
  95. package/dist/apps/admin/data-requests/index.d.ts +3 -0
  96. package/dist/apps/admin/data-requests/index.js +52 -72
  97. package/dist/apps/admin/distribution-lists/[uid].d.ts +7 -0
  98. package/dist/apps/admin/distribution-lists/[uid].js +1 -1
  99. package/dist/apps/admin/distribution-lists/index.d.ts +3 -0
  100. package/dist/apps/admin/distribution-lists/new/index.d.ts +3 -0
  101. package/dist/apps/admin/domains/[uid].d.ts +7 -0
  102. package/dist/apps/admin/domains/index.d.ts +3 -0
  103. package/dist/apps/admin/domains/new/index.d.ts +3 -0
  104. package/dist/apps/admin/encryption-policy/index.d.ts +3 -0
  105. package/dist/apps/admin/escrow-scopes/[uid].d.ts +21 -0
  106. package/dist/apps/admin/escrow-scopes/[uid].js +91 -12
  107. package/dist/apps/admin/escrow-scopes/index.d.ts +3 -0
  108. package/dist/apps/admin/escrow-scopes/new/index.d.ts +3 -0
  109. package/dist/apps/admin/escrow-scopes/new/index.js +8 -3
  110. package/dist/apps/admin/index.d.ts +3 -0
  111. package/dist/apps/admin/index.js +4 -1
  112. package/dist/apps/admin/ingest-queue/index.d.ts +4 -0
  113. package/dist/apps/admin/ingest-queue/index.js +24 -6
  114. package/dist/apps/admin/mailbox-policy/index.d.ts +3 -0
  115. package/dist/apps/admin/mailboxes/[uid].d.ts +7 -0
  116. package/dist/apps/admin/mailboxes/[uid].js +20 -4
  117. package/dist/apps/admin/mailboxes/new/index.d.ts +3 -0
  118. package/dist/apps/admin/plugins/index.d.ts +3 -0
  119. package/dist/apps/admin/quarantine/index.d.ts +6 -0
  120. package/dist/apps/admin/quarantine/index.js +20 -11
  121. package/dist/apps/admin/retention-policy/index.d.ts +3 -0
  122. package/dist/apps/admin/setup/index.d.ts +3 -0
  123. package/dist/apps/admin/transport-rules/[uid].d.ts +7 -0
  124. package/dist/apps/admin/transport-rules/[uid].js +18 -2
  125. package/dist/apps/admin/transport-rules/_transportRuleConfig.d.ts +21 -0
  126. package/dist/apps/admin/transport-rules/_transportRuleConfig.js +19 -0
  127. package/dist/apps/admin/transport-rules/index.d.ts +3 -0
  128. package/dist/apps/admin/transport-rules/index.js +22 -6
  129. package/dist/apps/admin/transport-rules/new/index.d.ts +3 -0
  130. package/dist/apps/admin/transport-rules/new/index.js +18 -2
  131. package/dist/apps/escrow/_layout.d.ts +10 -0
  132. package/dist/apps/escrow/_layout.js +3 -3
  133. package/dist/apps/escrow/audit-log/index.d.ts +9 -0
  134. package/dist/apps/escrow/audit-log/index.js +26 -1
  135. package/dist/apps/escrow/index.d.ts +3 -0
  136. package/dist/apps/escrow/matters/[uid].d.ts +7 -0
  137. package/dist/apps/escrow/matters/[uid].js +77 -42
  138. package/dist/apps/escrow/matters/new/index.d.ts +3 -0
  139. package/dist/apps/shared/components/admin/distributionLists/MemberListCard.d.ts +17 -0
  140. package/dist/apps/shared/components/admin/escrowScopes/EscrowScopeKeyAndHoldersFields.d.ts +32 -0
  141. package/dist/apps/shared/components/admin/escrowScopes/EscrowScopeKeyAndHoldersFields.js +11 -2
  142. package/dist/apps/shared/components/admin/layout/AdminShell.d.ts +32 -0
  143. package/dist/apps/shared/components/admin/layout/AdminShell.js +15 -6
  144. package/dist/apps/shared/components/admin/mailboxes/EscrowScopeCard.d.ts +12 -0
  145. package/dist/apps/shared/components/admin/mailboxes/EscrowScopeCard.js +72 -0
  146. package/dist/apps/shared/components/admin/mailboxes/MailboxTable.d.ts +6 -0
  147. package/dist/apps/shared/components/admin/mailboxes/ResourceSettingsCard.d.ts +19 -0
  148. package/dist/apps/shared/components/admin/mailboxes/ResourceSettingsCard.js +3 -3
  149. package/dist/apps/shared/components/admin/mailboxes/ShareAccessCard.d.ts +12 -0
  150. package/dist/apps/shared/components/admin/mailboxes/ShareAccessCard.js +22 -4
  151. package/dist/apps/shared/components/admin/settings/BrandingForm.d.ts +9 -0
  152. package/dist/apps/shared/components/admin/settings/BrandingForm.js +15 -4
  153. package/dist/apps/shared/components/admin/settings/DomainDnsSetup.d.ts +12 -0
  154. package/dist/apps/shared/components/admin/settings/DomainDnsSetup.js +13 -7
  155. package/dist/apps/shared/components/admin/settings/EncryptionPolicyForm.d.ts +12 -0
  156. package/dist/apps/shared/components/admin/settings/EncryptionPolicyForm.js +7 -2
  157. package/dist/apps/shared/components/admin/settings/LoadedSettingsForm.d.ts +9 -0
  158. package/dist/apps/shared/components/admin/settings/MailboxCreateForm.d.ts +19 -0
  159. package/dist/apps/shared/components/admin/settings/MailboxCreateForm.js +6 -0
  160. package/dist/apps/shared/components/admin/settings/MailboxPolicyForm.d.ts +10 -0
  161. package/dist/apps/shared/components/admin/settings/MailboxPolicyForm.js +34 -12
  162. package/dist/apps/shared/components/admin/settings/PluginsManager.d.ts +4 -0
  163. package/dist/apps/shared/components/admin/settings/PluginsManager.js +390 -78
  164. package/dist/apps/shared/components/admin/settings/RetentionPolicyForm.d.ts +9 -0
  165. package/dist/apps/shared/components/admin/settings/RetentionPolicyForm.js +40 -11
  166. package/dist/apps/shared/components/admin/setup/EscrowSetupStep.d.ts +14 -0
  167. package/dist/apps/shared/components/admin/setup/EscrowSetupStep.js +29 -13
  168. package/dist/apps/shared/components/admin/setup/SetupWizard.d.ts +36 -0
  169. package/dist/apps/shared/components/admin/setup/SetupWizard.js +87 -21
  170. package/dist/apps/shared/components/admin/signOut.d.ts +23 -0
  171. package/dist/apps/shared/components/admin/signOut.js +75 -0
  172. package/dist/apps/shared/components/admin/usePagedList.d.ts +39 -0
  173. package/dist/apps/shared/components/admin/usePagedList.js +99 -0
  174. package/dist/apps/shared/components/calendar/CalendarListSidebar.d.ts +26 -0
  175. package/dist/apps/shared/components/calendar/EventModal.d.ts +46 -0
  176. package/dist/apps/shared/components/calendar/EventModal.js +142 -21
  177. package/dist/apps/shared/components/calendar/MonthView.d.ts +15 -0
  178. package/dist/apps/shared/components/calendar/MonthView.js +12 -5
  179. package/dist/apps/shared/components/calendar/RecurrenceEditor.d.ts +20 -0
  180. package/dist/apps/shared/components/calendar/RecurrenceEditor.js +40 -5
  181. package/dist/apps/shared/components/calendar/ResourcePicker.d.ts +19 -0
  182. package/dist/apps/shared/components/calendar/SplitDayView.d.ts +28 -0
  183. package/dist/apps/shared/components/calendar/SplitDayView.js +10 -4
  184. package/dist/apps/shared/components/calendar/TimeGridView.d.ts +17 -0
  185. package/dist/apps/shared/components/calendar/TimeGridView.js +23 -7
  186. package/dist/apps/shared/components/calendar/allDay.d.ts +51 -0
  187. package/dist/apps/shared/components/calendar/allDay.js +111 -0
  188. package/dist/apps/shared/components/calendar/layout/CalendarShell.d.ts +40 -0
  189. package/dist/apps/shared/components/calendar/layout/CalendarShell.js +3 -3
  190. package/dist/apps/shared/components/contacts/ContactDetailPane.d.ts +23 -0
  191. package/dist/apps/shared/components/contacts/ContactDetailPane.js +43 -5
  192. package/dist/apps/shared/components/contacts/ContactForm.d.ts +20 -0
  193. package/dist/apps/shared/components/contacts/ContactForm.js +32 -10
  194. package/dist/apps/shared/components/contacts/ContactsSidebar.d.ts +40 -0
  195. package/dist/apps/shared/components/contacts/ContactsSidebar.js +2 -2
  196. package/dist/apps/shared/components/contacts/ContactsToolbar.d.ts +25 -0
  197. package/dist/apps/shared/components/contacts/KeyChangeReview.d.ts +40 -0
  198. package/dist/apps/shared/components/contacts/KeyChangeReview.js +63 -0
  199. package/dist/apps/shared/components/contacts/contactKeys.d.ts +29 -0
  200. package/dist/apps/shared/components/contacts/contactKeys.js +64 -0
  201. package/dist/apps/shared/components/contacts/layout/ContactsShell.d.ts +21 -0
  202. package/dist/apps/shared/components/contacts/layout/ContactsShell.js +2 -2
  203. package/dist/apps/shared/components/escrow/layout/EscrowShell.d.ts +25 -0
  204. package/dist/apps/shared/components/escrow/layout/EscrowShell.js +24 -5
  205. package/dist/apps/shared/components/forms/StringListField.d.ts +22 -0
  206. package/dist/apps/shared/components/layout/AppShell.d.ts +49 -0
  207. package/dist/apps/shared/components/layout/AppShell.js +97 -26
  208. package/dist/apps/shared/components/layout/BrandingChrome.d.ts +18 -0
  209. package/dist/apps/shared/components/layout/BrandingChrome.js +45 -10
  210. package/dist/apps/shared/components/layout/KeyEnrollmentGate.d.ts +51 -0
  211. package/dist/apps/shared/components/layout/KeyEnrollmentGate.js +49 -12
  212. package/dist/apps/shared/components/layout/MailboxProvisioning.d.ts +13 -0
  213. package/dist/apps/shared/components/layout/MailboxProvisioning.js +10 -2
  214. package/dist/apps/shared/components/layout/RecoveryCodeUnlock.d.ts +66 -0
  215. package/dist/apps/shared/components/layout/RecoveryCodeUnlock.js +174 -0
  216. package/dist/apps/shared/components/layout/UnlockPromptProvider.d.ts +45 -0
  217. package/dist/apps/shared/components/layout/UnlockPromptProvider.js +73 -14
  218. package/dist/apps/shared/components/layout/UserMenu.d.ts +23 -0
  219. package/dist/apps/shared/components/mail/ConversationList.d.ts +11 -0
  220. package/dist/apps/shared/components/mail/ConversationThreadPane.d.ts +23 -0
  221. package/dist/apps/shared/components/mail/ConversationThreadPane.js +50 -12
  222. package/dist/apps/shared/components/mail/MessageDetailPane.d.ts +93 -0
  223. package/dist/apps/shared/components/mail/MessageDetailPane.js +441 -36
  224. package/dist/apps/shared/components/mail/compose/ComposeContext.d.ts +58 -0
  225. package/dist/apps/shared/components/mail/compose/ComposeContext.js +9 -6
  226. package/dist/apps/shared/components/mail/compose/ComposeToolbar.d.ts +15 -0
  227. package/dist/apps/shared/components/mail/compose/ComposeWindow.d.ts +37 -0
  228. package/dist/apps/shared/components/mail/compose/ComposeWindow.js +699 -128
  229. package/dist/apps/shared/components/mail/compose/EmojiPicker.d.ts +14 -0
  230. package/dist/apps/shared/components/mail/compose/GifPicker.d.ts +13 -0
  231. package/dist/apps/shared/components/mail/compose/RichTextEditor.d.ts +34 -0
  232. package/dist/apps/shared/components/mail/compose/ScheduleSendPicker.d.ts +16 -0
  233. package/dist/apps/shared/components/mail/compose/composeFlushRegistry.d.ts +27 -0
  234. package/dist/apps/shared/components/mail/compose/composeFlushRegistry.js +50 -0
  235. package/dist/apps/shared/components/mail/layout/MailShell.d.ts +57 -0
  236. package/dist/apps/shared/components/mail/layout/MailShell.js +13 -4
  237. package/dist/apps/shared/components/mail/pinnedSigners.d.ts +33 -0
  238. package/dist/apps/shared/components/mail/pinnedSigners.js +98 -0
  239. package/dist/apps/shared/components/mail/verificationSeals.d.ts +22 -0
  240. package/dist/apps/shared/components/mail/verificationSeals.js +112 -0
  241. package/dist/apps/shared/components/mail/writableMailboxes.d.ts +15 -0
  242. package/dist/apps/shared/components/mail/writableMailboxes.js +87 -0
  243. package/dist/apps/shared/components/rules/RuleBuilder.d.ts +70 -0
  244. package/dist/apps/shared/components/rules/RuleBuilder.js +34 -6
  245. package/dist/apps/shared/components/settings/layout/SettingsShell.d.ts +41 -0
  246. package/dist/apps/shared/components/settings/layout/SettingsShell.js +19 -9
  247. package/dist/apps/shared/components/tasks/TasksSidebar.d.ts +41 -0
  248. package/dist/apps/shared/components/tasks/TasksToolbar.d.ts +14 -0
  249. package/dist/apps/shared/components/tasks/layout/TasksShell.d.ts +24 -0
  250. package/dist/apps/shared/components/tasks/layout/TasksShell.js +2 -2
  251. package/dist/apps/shared/mail/findWellKnownFolderUid.d.ts +5 -0
  252. package/dist/apps/shared/mail/listAllPages.d.ts +17 -0
  253. package/dist/apps/shared/mail/listAllPages.js +25 -0
  254. package/dist/apps/shared/plugins/pluginNav.d.ts +39 -0
  255. package/dist/apps/shared/plugins/pluginNav.js +33 -0
  256. package/dist/apps/shared/search/LocalIndexLifecycle.d.ts +13 -0
  257. package/dist/apps/shared/search/LocalIndexLifecycle.js +58 -54
  258. package/dist/apps/shared/search/localIndexBlockCipher.d.ts +36 -0
  259. package/dist/apps/shared/search/localIndexBuilder.d.ts +85 -0
  260. package/dist/apps/shared/search/localIndexBuilder.js +292 -37
  261. package/dist/apps/shared/search/localIndexKey.d.ts +4 -0
  262. package/dist/apps/shared/search/localIndexRpcClient.d.ts +71 -0
  263. package/dist/apps/shared/search/localIndexRpcClient.js +191 -26
  264. package/dist/apps/shared/search/localIndexSchema.d.ts +111 -0
  265. package/dist/apps/shared/search/localIndexSchema.js +12 -6
  266. package/dist/apps/shared/search/localIndexSizePreference.d.ts +27 -0
  267. package/dist/apps/shared/search/localIndexStorage.d.ts +28 -0
  268. package/dist/apps/shared/search/localIndexStorage.js +86 -0
  269. package/dist/apps/shared/search/localIndexVFS.d.ts +101 -0
  270. package/dist/apps/shared/search/localIndexVFS.js +68 -40
  271. package/dist/apps/shared/search/localIndexWorker.d.ts +145 -0
  272. package/dist/apps/shared/search/localIndexWorker.js +519 -173
  273. package/dist/apps/shared/search/searchTier2.d.ts +30 -0
  274. package/dist/apps/www/_404.d.ts +2 -0
  275. package/dist/apps/www/_500.d.ts +2 -0
  276. package/dist/apps/www/_layout.d.ts +14 -0
  277. package/dist/apps/www/calendar/index.d.ts +3 -0
  278. package/dist/apps/www/calendar/index.js +28 -10
  279. package/dist/apps/www/contacts/[uid].d.ts +13 -0
  280. package/dist/apps/www/contacts/[uid].js +13 -2
  281. package/dist/apps/www/contacts/index.d.ts +3 -0
  282. package/dist/apps/www/contacts/index.js +80 -10
  283. package/dist/apps/www/index.d.ts +3 -0
  284. package/dist/apps/www/index.js +339 -108
  285. package/dist/apps/www/messages/[uid].d.ts +11 -0
  286. package/dist/apps/www/messages/[uid].js +18 -6
  287. package/dist/apps/www/settings/auto-reply/index.d.ts +4 -0
  288. package/dist/apps/www/settings/auto-reply/index.js +9 -4
  289. package/dist/apps/www/settings/encryption/index.d.ts +7 -0
  290. package/dist/apps/www/settings/encryption/index.js +514 -97
  291. package/dist/apps/www/settings/filters/[uid].d.ts +8 -0
  292. package/dist/apps/www/settings/filters/[uid].js +22 -7
  293. package/dist/apps/www/settings/filters/_mailFilterRuleConfig.d.ts +11 -0
  294. package/dist/apps/www/settings/filters/index.d.ts +4 -0
  295. package/dist/apps/www/settings/filters/new/index.d.ts +4 -0
  296. package/dist/apps/www/settings/filters/new/index.js +8 -2
  297. package/dist/apps/www/settings/focused-inbox/index.d.ts +4 -0
  298. package/dist/apps/www/settings/focused-inbox/index.js +3 -1
  299. package/dist/apps/www/settings/labels/index.d.ts +4 -0
  300. package/dist/apps/www/settings/privacy/index.d.ts +4 -0
  301. package/dist/apps/www/settings/privacy/index.js +57 -22
  302. package/dist/apps/www/settings/read-receipts/index.d.ts +4 -0
  303. package/dist/apps/www/settings/read-receipts/index.js +10 -3
  304. package/dist/apps/www/settings/sharing/index.d.ts +4 -0
  305. package/dist/apps/www/settings/sharing/index.js +7 -11
  306. package/dist/apps/www/settings/signatures/[uid].d.ts +8 -0
  307. package/dist/apps/www/settings/signatures/index.d.ts +4 -0
  308. package/dist/apps/www/settings/signatures/new/index.d.ts +4 -0
  309. package/dist/apps/www/settings/signatures/signatureDefaults.d.ts +10 -0
  310. package/dist/apps/www/tasks/index.d.ts +3 -0
  311. package/dist/apps/www/tasks/index.js +50 -10
  312. package/package.json +3 -3
  313. package/apps/shared/components/booking/AvailabilityEditor.tsx +0 -118
  314. package/apps/www/settings/booking-types/[uid].tsx +0 -300
  315. package/apps/www/settings/booking-types/index.tsx +0 -98
  316. package/apps/www/settings/booking-types/new/index.tsx +0 -212
  317. package/dist/apps/shared/components/booking/AvailabilityEditor.js +0 -45
  318. package/dist/apps/www/settings/booking-types/[uid].js +0 -129
  319. package/dist/apps/www/settings/booking-types/index.js +0 -29
  320. package/dist/apps/www/settings/booking-types/new/index.js +0 -86
@@ -1,181 +1,216 @@
1
- ///////////////////////////////////////////////////////////////////////////////
2
- // Copyright (C) 2026 Jean-Philippe Steinmetz
3
- // SPDX-License-Identifier: MPL-2.0
4
- ///////////////////////////////////////////////////////////////////////////////
5
- import React, { useEffect, useState } from "react";
6
- import { ApiRequestError } from "@rapidmx/react-shared/util/api.js";
7
- import { Attachment, Folder, Message, getMessage, listAttachments, setMessageRead } from "@rapidmx/react-shared/mail/mailApi.js";
8
- import { ConversationSummary } from "@rapidmx/react-shared/mail/conversationsApi.js";
9
- import { Label } from "@rapidmx/react-shared/mail/labelsApi.js";
10
- import MessageDetailPane from "./MessageDetailPane.js";
11
- import Alert from "@rapidmx/react-shared/components/feedback/Alert.js";
12
-
13
- export interface ConversationThreadPaneProps {
14
- conversation: ConversationSummary | null;
15
- /** The mailbox's full folder list — a conversation can span folders (e.g. an Inbox message and the
16
- * Sent Items copy of its reply), so each message's own recall eligibility is looked up individually
17
- * against its own `folderUid` rather than assuming one folder for the whole thread. */
18
- folders: Folder[];
19
- /** The mailbox's labels, fetched once by the parent (`apps/www/index.tsx`) and passed through to
20
- * every expanded message's own `MessageDetailPane` — see that component's own `labels` prop. */
21
- labels?: Label[];
22
- }
23
-
24
- /**
25
- * The merged, Gmail-style reading pane for "By conversation" mode — every message in the conversation
26
- * fetched and stacked oldest-to-newest, all but the most recent collapsed to a one-line summary
27
- * (sender + subject) until clicked. Reuses `MessageDetailPane` for each *expanded* message's own
28
- * header/attachments/body-iframe rendering rather than re-implementing it; a collapsed row is its own
29
- * lightweight summary, since mounting a full `MessageDetailPane` (and its iframe) for every message in
30
- * a long thread up front would be wasteful.
31
- */
32
- export default function ConversationThreadPane({ conversation, folders, labels }: ConversationThreadPaneProps) {
33
- const [messages, setMessages] = useState<Record<string, Message>>({});
34
- const [attachmentsByUid, setAttachmentsByUid] = useState<Record<string, Attachment[]>>({});
35
- const [expandedUids, setExpandedUids] = useState<Set<string>>(new Set());
36
- const [loading, setLoading] = useState(false);
37
- const [error, setError] = useState<string | null>(null);
38
-
39
- useEffect(() => {
40
- if (!conversation) {
41
- setMessages({});
42
- setExpandedUids(new Set());
43
- return;
44
- }
45
- setLoading(true);
46
- setError(null);
47
- Promise.all(conversation.messageUids.map((uid) => getMessage(uid)))
48
- .then((loaded) => {
49
- setMessages(Object.fromEntries(loaded.map((m) => [m.uid, m])));
50
- // `messageUids` always has at least one entry — a `ConversationSummary` only ever
51
- // exists because it was grouped from real messages (see
52
- // `BaseMessageRoute.conversations()`).
53
- const latestUid = conversation.messageUids[conversation.messageUids.length - 1];
54
- setExpandedUids(new Set([latestUid]));
55
- })
56
- .catch((err) => setError(err instanceof ApiRequestError ? err.message : "Could not load this conversation."))
57
- .finally(() => setLoading(false));
58
- }, [conversation?.conversationId]);
59
-
60
- // Lazily loads attachments and marks-as-read only for messages the reader has actually expanded —
61
- // mirrors `mailDetailHooks.ts`'s `useMessageAttachments`/`useMarkMessageRead`, reimplemented here
62
- // (rather than called in a loop, which the rules of hooks don't allow) since a thread can expand
63
- // more than one message at once, unlike the single-selected-message case those hooks were built for.
64
- useEffect(() => {
65
- for (const uid of expandedUids) {
66
- const message = messages[uid];
67
- if (!message) continue;
68
- if (message.hasAttachments && !attachmentsByUid[uid]) {
69
- listAttachments(message.folderUid, uid)
70
- .then((loaded) => setAttachmentsByUid((prev) => ({ ...prev, [uid]: loaded })))
71
- .catch(() => {
72
- // Best-effort, same as the mark-as-read catch below — `attachmentsByUid[uid] ??
73
- // []` already renders no attachments while this stays unset, so there is nothing
74
- // further to do on failure.
75
- });
76
- }
77
- if (!message.flags.read) {
78
- setMessageRead(message, true)
79
- .then((updated) => setMessages((prev) => ({ ...prev, [uid]: updated })))
80
- .catch(() => {
81
- // Best-effort — matches `useMarkMessageRead`'s own doc comment.
82
- });
83
- }
84
- }
85
- }, [expandedUids, messages]);
86
-
87
- function toggleExpanded(uid: string) {
88
- setExpandedUids((prev) => {
89
- const next = new Set(prev);
90
- if (next.has(uid)) {
91
- next.delete(uid);
92
- } else {
93
- next.add(uid);
94
- }
95
- return next;
96
- });
97
- }
98
-
99
- if (!conversation) {
100
- return <p className="p-8 text-sm text-text-muted">Select a conversation to read it.</p>;
101
- }
102
- if (loading) {
103
- return <p className="p-8 text-sm text-text-muted">Loading&hellip;</p>;
104
- }
105
- if (error) {
106
- return (
107
- <div className="p-4 flex-1">
108
- <Alert>{error}</Alert>
109
- </div>
110
- );
111
- }
112
-
113
- return (
114
- <div className="flex-1 min-w-0 flex flex-col overflow-y-auto">
115
- <div className="border-b border-border p-4">
116
- <h1 className="text-lg font-bold tracking-tight">{conversation.subject || "(no subject)"}</h1>
117
- <p className="text-sm text-text-muted mt-1">
118
- {conversation.messageCount} message{conversation.messageCount === 1 ? "" : "s"}
119
- </p>
120
- </div>
121
- {conversation.messageUids.map((uid) => {
122
- const message = messages[uid];
123
- if (!message) {
124
- return null;
125
- }
126
- const expanded = expandedUids.has(uid);
127
- if (!expanded) {
128
- return (
129
- <button
130
- key={uid}
131
- type="button"
132
- onClick={() => toggleExpanded(uid)}
133
- className={[
134
- "w-full text-left px-4 py-3 border-b border-border hover:bg-surface-alt",
135
- message.flags.read ? "" : "font-semibold",
136
- ].join(" ")}
137
- >
138
- <div className="flex items-center justify-between gap-2 text-sm">
139
- <span className="truncate">{message.from.displayName || message.from.address}</span>
140
- <span className="text-xs text-text-muted shrink-0">
141
- {new Date(message.receivedDate).toLocaleString()}
142
- </span>
143
- </div>
144
- <div className="text-xs text-text-muted truncate font-normal">{message.bodyPreview}</div>
145
- </button>
146
- );
147
- }
148
- return (
149
- <div key={uid} className="border-b border-border">
150
- <button
151
- type="button"
152
- onClick={() => toggleExpanded(uid)}
153
- className="w-full text-left px-4 pt-2 text-xs text-text-muted hover:text-text"
154
- >
155
- Collapse
156
- </button>
157
- <MessageDetailPane
158
- message={message}
159
- attachments={attachmentsByUid[uid] ?? []}
160
- isSentItems={folders.find((f) => f.uid === message.folderUid)?.type === "sent_items"}
161
- onRecalled={(updated) => setMessages((prev) => ({ ...prev, [uid]: updated }))}
162
- isOutbox={folders.find((f) => f.uid === message.folderUid)?.type === "outbox"}
163
- draftsFolderUid={folders.find((f) => f.type === "drafts")?.uid}
164
- // Unlike `apps/www/index.tsx`'s list-removal behavior, this patches the
165
- // message in place (same as `onRecalled` above) rather than removing it from
166
- // the conversation — `conversation.messageUids` is owned by the parent, not
167
- // this component, so there's no membership list here to remove it from.
168
- onScheduledSendCanceled={(updated) => setMessages((prev) => ({ ...prev, [uid]: updated }))}
169
- isInbox={folders.find((f) => f.uid === message.folderUid)?.type === "inbox"}
170
- onClassified={(updated) => setMessages((prev) => ({ ...prev, [uid]: updated }))}
171
- onReceiptHandled={(updated) => setMessages((prev) => ({ ...prev, [uid]: updated }))}
172
- onArchived={(updated) => setMessages((prev) => ({ ...prev, [uid]: updated }))}
173
- labels={labels}
174
- onLabelsChanged={(updated) => setMessages((prev) => ({ ...prev, [uid]: updated }))}
175
- />
176
- </div>
177
- );
178
- })}
179
- </div>
180
- );
181
- }
1
+ ///////////////////////////////////////////////////////////////////////////////
2
+ // Copyright (C) 2026 Jean-Philippe Steinmetz
3
+ // SPDX-License-Identifier: MPL-2.0
4
+ ///////////////////////////////////////////////////////////////////////////////
5
+ import React, { useEffect, useRef, useState } from "react";
6
+ import { ApiRequestError } from "@rapidmx/react-shared/util/api.js";
7
+ import { Attachment, Folder, Message, getMessage, listAttachments, setMessageRead } from "@rapidmx/react-shared/mail/mailApi.js";
8
+ import { ConversationSummary } from "@rapidmx/react-shared/mail/conversationsApi.js";
9
+ import { Label } from "@rapidmx/react-shared/mail/labelsApi.js";
10
+ import MessageDetailPane from "./MessageDetailPane.js";
11
+ import Alert from "@rapidmx/react-shared/components/feedback/Alert.js";
12
+
13
+ export interface ConversationThreadPaneProps {
14
+ conversation: ConversationSummary | null;
15
+ /** The mailbox's full folder list — a conversation can span folders (e.g. an Inbox message and the
16
+ * Sent Items copy of its reply), so each message's own recall eligibility is looked up individually
17
+ * against its own `folderUid` rather than assuming one folder for the whole thread. */
18
+ folders: Folder[];
19
+ /** The mailbox's labels, fetched once by the parent (`apps/www/index.tsx`) and passed through to
20
+ * every expanded message's own `MessageDetailPane` — see that component's own `labels` prop. */
21
+ labels?: Label[];
22
+ }
23
+
24
+ /**
25
+ * The merged, Gmail-style reading pane for "By conversation" mode — every message in the conversation
26
+ * fetched and stacked oldest-to-newest, all but the most recent collapsed to a one-line summary
27
+ * (sender + subject) until clicked. Reuses `MessageDetailPane` for each *expanded* message's own
28
+ * header/attachments/body-iframe rendering rather than re-implementing it; a collapsed row is its own
29
+ * lightweight summary, since mounting a full `MessageDetailPane` (and its iframe) for every message in
30
+ * a long thread up front would be wasteful.
31
+ */
32
+ export default function ConversationThreadPane({ conversation, folders, labels }: ConversationThreadPaneProps) {
33
+ const [messages, setMessages] = useState<Record<string, Message>>({});
34
+ const [attachmentsByUid, setAttachmentsByUid] = useState<Record<string, Attachment[]>>({});
35
+ const [expandedUids, setExpandedUids] = useState<Set<string>>(new Set());
36
+ const [loading, setLoading] = useState(false);
37
+ const [error, setError] = useState<string | null>(null);
38
+
39
+ // Bumped on every conversation switch - any in-flight load/attachments/mark-read response carrying an
40
+ // older generation belongs to a superseded conversation and is dropped rather than applied.
41
+ const generationRef = useRef(0);
42
+ // Message uids a mark-read / attachments request has already been issued for in the current
43
+ // generation, so re-running the effect below (every `messages`/`expandedUids` change) while one is
44
+ // still in flight never fires a duplicate - which for mark-read would also carry a stale `version`.
45
+ const markReadRequestedRef = useRef<Set<string>>(new Set());
46
+ const attachmentsRequestedRef = useRef<Set<string>>(new Set());
47
+
48
+ useEffect(() => {
49
+ const generation = ++generationRef.current;
50
+ markReadRequestedRef.current = new Set();
51
+ attachmentsRequestedRef.current = new Set();
52
+ setMessages({});
53
+ setAttachmentsByUid({});
54
+ setExpandedUids(new Set());
55
+ if (!conversation) {
56
+ setLoading(false);
57
+ return;
58
+ }
59
+ setLoading(true);
60
+ setError(null);
61
+ Promise.all(conversation.messageUids.map((uid) => getMessage(uid)))
62
+ .then((loaded) => {
63
+ if (generation !== generationRef.current) return;
64
+ setMessages(Object.fromEntries(loaded.map((m) => [m.uid, m])));
65
+ // `messageUids` always has at least one entry — a `ConversationSummary` only ever
66
+ // exists because it was grouped from real messages (see
67
+ // `BaseMessageRoute.conversations()`).
68
+ const latestUid = conversation.messageUids[conversation.messageUids.length - 1];
69
+ setExpandedUids(new Set([latestUid]));
70
+ })
71
+ .catch((err) => {
72
+ if (generation !== generationRef.current) return;
73
+ setError(err instanceof ApiRequestError ? err.message : "Could not load this conversation.");
74
+ })
75
+ .finally(() => {
76
+ if (generation === generationRef.current) setLoading(false);
77
+ });
78
+ }, [conversation?.conversationId]);
79
+
80
+ // Lazily loads attachments and marks-as-read only for messages the reader has actually expanded —
81
+ // mirrors `mailDetailHooks.ts`'s `useMessageAttachments`/`useMarkMessageRead`, reimplemented here
82
+ // (rather than called in a loop, which the rules of hooks don't allow) since a thread can expand
83
+ // more than one message at once, unlike the single-selected-message case those hooks were built for.
84
+ useEffect(() => {
85
+ const generation = generationRef.current;
86
+ for (const uid of expandedUids) {
87
+ const message = messages[uid];
88
+ if (!message) continue;
89
+ if (message.hasAttachments && !attachmentsRequestedRef.current.has(uid)) {
90
+ attachmentsRequestedRef.current.add(uid);
91
+ listAttachments(message.folderUid, uid)
92
+ .then((loaded) => {
93
+ if (generation === generationRef.current) {
94
+ setAttachmentsByUid((prev) => ({ ...prev, [uid]: loaded }));
95
+ }
96
+ })
97
+ .catch(() => {
98
+ // Best-effort, same as the mark-as-read catch below — `attachmentsByUid[uid] ??
99
+ // []` already renders no attachments while this stays unset; forgetting the
100
+ // request just lets a later re-expand retry it.
101
+ attachmentsRequestedRef.current.delete(uid);
102
+ });
103
+ }
104
+ // `message` is this render's latest copy, so the request carries its current `version`.
105
+ if (!message.flags.read && !markReadRequestedRef.current.has(uid)) {
106
+ markReadRequestedRef.current.add(uid);
107
+ setMessageRead(message, true)
108
+ .then((updated) => {
109
+ if (generation !== generationRef.current) return;
110
+ // Never clobber a newer copy another action (label/classify/...) already patched in.
111
+ setMessages((prev) => (prev[uid].version > updated.version ? prev : { ...prev, [uid]: updated }));
112
+ })
113
+ .catch(() => {
114
+ // Best-effort — matches `useMarkMessageRead`'s own doc comment. Forgetting the
115
+ // request lets a later effect run (e.g. a re-expand) retry with a fresh copy.
116
+ markReadRequestedRef.current.delete(uid);
117
+ });
118
+ }
119
+ }
120
+ }, [expandedUids, messages]);
121
+
122
+ function toggleExpanded(uid: string) {
123
+ setExpandedUids((prev) => {
124
+ const next = new Set(prev);
125
+ if (next.has(uid)) {
126
+ next.delete(uid);
127
+ } else {
128
+ next.add(uid);
129
+ }
130
+ return next;
131
+ });
132
+ }
133
+
134
+ if (!conversation) {
135
+ return <p className="p-8 text-sm text-text-muted">Select a conversation to read it.</p>;
136
+ }
137
+ if (loading) {
138
+ return <p className="p-8 text-sm text-text-muted">Loading&hellip;</p>;
139
+ }
140
+ if (error) {
141
+ return (
142
+ <div className="p-4 flex-1">
143
+ <Alert>{error}</Alert>
144
+ </div>
145
+ );
146
+ }
147
+
148
+ return (
149
+ <div className="flex-1 min-w-0 flex flex-col overflow-y-auto">
150
+ <div className="border-b border-border p-4">
151
+ <h1 className="text-lg font-bold tracking-tight">{conversation.subject || "(no subject)"}</h1>
152
+ <p className="text-sm text-text-muted mt-1">
153
+ {conversation.messageCount} message{conversation.messageCount === 1 ? "" : "s"}
154
+ </p>
155
+ </div>
156
+ {conversation.messageUids.map((uid) => {
157
+ const message = messages[uid];
158
+ if (!message) {
159
+ return null;
160
+ }
161
+ const expanded = expandedUids.has(uid);
162
+ if (!expanded) {
163
+ return (
164
+ <button
165
+ key={uid}
166
+ type="button"
167
+ onClick={() => toggleExpanded(uid)}
168
+ className={[
169
+ "w-full text-left px-4 py-3 border-b border-border hover:bg-surface-alt",
170
+ message.flags.read ? "" : "font-semibold",
171
+ ].join(" ")}
172
+ >
173
+ <div className="flex items-center justify-between gap-2 text-sm">
174
+ <span className="truncate">{message.from.displayName || message.from.address}</span>
175
+ <span className="text-xs text-text-muted shrink-0">
176
+ {new Date(message.receivedDate).toLocaleString()}
177
+ </span>
178
+ </div>
179
+ <div className="text-xs text-text-muted truncate font-normal">{message.bodyPreview}</div>
180
+ </button>
181
+ );
182
+ }
183
+ return (
184
+ <div key={uid} className="border-b border-border">
185
+ <button
186
+ type="button"
187
+ onClick={() => toggleExpanded(uid)}
188
+ className="w-full text-left px-4 pt-2 text-xs text-text-muted hover:text-text"
189
+ >
190
+ Collapse
191
+ </button>
192
+ <MessageDetailPane
193
+ message={message}
194
+ attachments={attachmentsByUid[uid] ?? []}
195
+ isSentItems={folders.find((f) => f.uid === message.folderUid)?.type === "sent_items"}
196
+ onRecalled={(updated) => setMessages((prev) => ({ ...prev, [uid]: updated }))}
197
+ isOutbox={folders.find((f) => f.uid === message.folderUid)?.type === "outbox"}
198
+ draftsFolderUid={folders.find((f) => f.type === "drafts")?.uid}
199
+ // Unlike `apps/www/index.tsx`'s list-removal behavior, this patches the
200
+ // message in place (same as `onRecalled` above) rather than removing it from
201
+ // the conversation — `conversation.messageUids` is owned by the parent, not
202
+ // this component, so there's no membership list here to remove it from.
203
+ onScheduledSendCanceled={(updated) => setMessages((prev) => ({ ...prev, [uid]: updated }))}
204
+ isInbox={folders.find((f) => f.uid === message.folderUid)?.type === "inbox"}
205
+ onClassified={(updated) => setMessages((prev) => ({ ...prev, [uid]: updated }))}
206
+ onReceiptHandled={(updated) => setMessages((prev) => ({ ...prev, [uid]: updated }))}
207
+ onArchived={(updated) => setMessages((prev) => ({ ...prev, [uid]: updated }))}
208
+ labels={labels}
209
+ onLabelsChanged={(updated) => setMessages((prev) => ({ ...prev, [uid]: updated }))}
210
+ />
211
+ </div>
212
+ );
213
+ })}
214
+ </div>
215
+ );
216
+ }