@rapidmx/web-client 0.21.0 → 0.23.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 (897) hide show
  1. package/README.md +48 -14
  2. package/apps/admin/_layout.tsx +2 -2
  3. package/apps/admin/audit-log/index.tsx +4 -4
  4. package/apps/admin/branding/index.tsx +3 -3
  5. package/apps/admin/data-requests/index.tsx +8 -8
  6. package/apps/admin/distribution-lists/[uid].tsx +3 -3
  7. package/apps/admin/distribution-lists/index.tsx +4 -4
  8. package/apps/admin/distribution-lists/new/index.tsx +5 -5
  9. package/apps/admin/domains/[uid].tsx +6 -6
  10. package/apps/admin/domains/index.tsx +4 -4
  11. package/apps/admin/domains/new/index.tsx +5 -5
  12. package/apps/admin/encryption-policy/index.tsx +1 -1
  13. package/apps/admin/escrow-scopes/[uid].tsx +7 -7
  14. package/apps/admin/escrow-scopes/index.tsx +4 -4
  15. package/apps/admin/escrow-scopes/new/index.tsx +5 -5
  16. package/apps/admin/index.tsx +6 -6
  17. package/apps/admin/ingest-queue/index.tsx +4 -4
  18. package/apps/admin/mailbox-policy/index.tsx +1 -1
  19. package/apps/admin/mailboxes/[uid].tsx +5 -5
  20. package/apps/admin/quarantine/index.tsx +5 -5
  21. package/apps/admin/retention-policy/index.tsx +3 -3
  22. package/apps/admin/signing-certificates/index.tsx +5 -5
  23. package/apps/admin/transport-rules/[uid].tsx +5 -5
  24. package/apps/admin/transport-rules/_transportRuleConfig.tsx +3 -3
  25. package/apps/admin/transport-rules/index.tsx +4 -4
  26. package/apps/admin/transport-rules/new/index.tsx +5 -5
  27. package/apps/escrow/_layout.tsx +1 -1
  28. package/apps/escrow/audit-log/index.tsx +4 -4
  29. package/apps/escrow/index.tsx +4 -4
  30. package/apps/escrow/matters/[uid].tsx +10 -10
  31. package/apps/escrow/matters/new/index.tsx +6 -6
  32. package/apps/shared/appearance/AppearanceForm.tsx +3 -3
  33. package/apps/shared/appearance/AppearanceHead.tsx +1 -1
  34. package/apps/shared/appearance/AppearanceProvider.tsx +3 -3
  35. package/apps/shared/appearance/appearanceCache.ts +1 -1
  36. package/apps/shared/appearance/appearanceContext.ts +1 -1
  37. package/apps/shared/appearance/theme.ts +1 -1
  38. package/apps/shared/auth/adminAccess.ts +1 -1
  39. package/apps/shared/calendar/bookingPlugin.ts +1 -1
  40. package/apps/shared/calendar/calendarLiveUpdates.ts +1 -1
  41. package/apps/shared/calendar/calendarReminders.ts +1 -1
  42. package/apps/shared/calendar/useCalendarReminders.ts +1 -1
  43. package/apps/shared/components/admin/diagnostics/DiagnosticsManager.tsx +1 -1
  44. package/apps/shared/components/admin/diagnostics/InstalledPlugins.tsx +2 -2
  45. package/apps/shared/components/admin/diagnostics/LogsPanel.tsx +2 -2
  46. package/apps/shared/components/admin/diagnostics/PackagesTable.tsx +1 -1
  47. package/apps/shared/components/admin/diagnostics/RuntimePanel.tsx +1 -1
  48. package/apps/shared/components/admin/diagnostics/SystemPanel.tsx +2 -2
  49. package/apps/shared/components/admin/diagnostics/VersionsPanel.tsx +1 -1
  50. package/apps/shared/components/admin/diagnostics/diagnosticsApi.ts +1 -1
  51. package/apps/shared/components/admin/diagnostics/format.ts +1 -1
  52. package/apps/shared/components/admin/diagnostics/logClient.ts +1 -1
  53. package/apps/shared/components/admin/distributionLists/MemberListCard.tsx +4 -4
  54. package/apps/shared/components/admin/elevation.ts +1 -1
  55. package/apps/shared/components/admin/escrowScopes/EscrowScopeKeyAndHoldersFields.tsx +3 -3
  56. package/apps/shared/components/admin/layout/AdminShell.tsx +8 -8
  57. package/apps/shared/components/admin/mailboxes/EraseLeftoverDataDialog.tsx +6 -6
  58. package/apps/shared/components/admin/mailboxes/EscrowScopeCard.tsx +10 -8
  59. package/apps/shared/components/admin/mailboxes/LeftoverMailboxesSection.tsx +4 -4
  60. package/apps/shared/components/admin/mailboxes/MailboxTable.tsx +1 -1
  61. package/apps/shared/components/admin/mailboxes/ResourceSettingsCard.tsx +19 -14
  62. package/apps/shared/components/admin/mailboxes/ShareAccessCard.tsx +5 -5
  63. package/apps/shared/components/admin/settings/BrandingForm.tsx +5 -5
  64. package/apps/shared/components/admin/settings/DomainDnsSetup.tsx +5 -5
  65. package/apps/shared/components/admin/settings/EncryptionPolicyForm.tsx +4 -4
  66. package/apps/shared/components/admin/settings/LoadedSettingsForm.tsx +2 -2
  67. package/apps/shared/components/admin/settings/MailboxCreateForm.tsx +32 -27
  68. package/apps/shared/components/admin/settings/MailboxPolicyForm.tsx +4 -4
  69. package/apps/shared/components/admin/settings/PluginsManager.tsx +5 -5
  70. package/apps/shared/components/admin/settings/RetentionPolicyForm.tsx +5 -5
  71. package/apps/shared/components/admin/setup/EscrowSetupStep.tsx +7 -7
  72. package/apps/shared/components/admin/setup/SetupWizard.tsx +28 -24
  73. package/apps/shared/components/admin/signOut.ts +1 -1
  74. package/apps/shared/components/admin/usePagedList.tsx +2 -2
  75. package/apps/shared/components/calendar/AppointmentQuickForm.tsx +3 -3
  76. package/apps/shared/components/calendar/CalendarListSidebar.tsx +3 -3
  77. package/apps/shared/components/calendar/DescriptionEditor.tsx +1 -1
  78. package/apps/shared/components/calendar/EventDescriptionView.tsx +1 -1
  79. package/apps/shared/components/calendar/EventDetails.tsx +16 -14
  80. package/apps/shared/components/calendar/EventEditor.tsx +54 -39
  81. package/apps/shared/components/calendar/EventExpandedForm.tsx +3 -3
  82. package/apps/shared/components/calendar/EventFormParts.tsx +2 -2
  83. package/apps/shared/components/calendar/EventModal.tsx +5 -5
  84. package/apps/shared/components/calendar/EventQuickForm.tsx +3 -3
  85. package/apps/shared/components/calendar/EventShell.tsx +1 -1
  86. package/apps/shared/components/calendar/FindATime.tsx +6 -4
  87. package/apps/shared/components/calendar/GuestInput.tsx +2 -2
  88. package/apps/shared/components/calendar/MonthView.tsx +2 -2
  89. package/apps/shared/components/calendar/QuickCreateFaces.tsx +1 -1
  90. package/apps/shared/components/calendar/QuickFaceFrame.tsx +1 -1
  91. package/apps/shared/components/calendar/RecurrenceEditor.tsx +2 -2
  92. package/apps/shared/components/calendar/RequestChangeForm.tsx +8 -6
  93. package/apps/shared/components/calendar/ResourcePicker.tsx +7 -5
  94. package/apps/shared/components/calendar/SplitDayView.tsx +1 -1
  95. package/apps/shared/components/calendar/TaskQuickForm.tsx +23 -18
  96. package/apps/shared/components/calendar/TimeGridView.tsx +5 -3
  97. package/apps/shared/components/calendar/allDay.ts +2 -2
  98. package/apps/shared/components/calendar/eventDialogFields.ts +3 -3
  99. package/apps/shared/components/calendar/eventForm.ts +3 -3
  100. package/apps/shared/components/calendar/eventFormat.ts +3 -3
  101. package/apps/shared/components/calendar/findTimeGrid.ts +2 -2
  102. package/apps/shared/components/calendar/layout/CalendarShell.tsx +11 -9
  103. package/apps/shared/components/contacts/ContactDetailPane.tsx +4 -4
  104. package/apps/shared/components/contacts/ContactForm.tsx +27 -17
  105. package/apps/shared/components/contacts/ContactsSidebar.tsx +7 -5
  106. package/apps/shared/components/contacts/KeyChangeReview.tsx +5 -5
  107. package/apps/shared/components/contacts/contactKeys.ts +3 -3
  108. package/apps/shared/components/contacts/layout/ContactsShell.tsx +9 -7
  109. package/apps/shared/components/escrow/layout/EscrowShell.tsx +6 -6
  110. package/apps/shared/components/forms/StringListField.tsx +1 -1
  111. package/apps/shared/components/layout/AppShell.tsx +12 -10
  112. package/apps/shared/components/layout/BrandingChrome.tsx +1 -1
  113. package/apps/shared/components/layout/KeyEnrollmentGate.tsx +9 -9
  114. package/apps/shared/components/layout/MailboxProvisioning.tsx +8 -6
  115. package/apps/shared/components/layout/RecoveryCodeUnlock.tsx +9 -9
  116. package/apps/shared/components/layout/ThemeSwitch.tsx +1 -1
  117. package/apps/shared/components/layout/UnlockPromptProvider.tsx +6 -6
  118. package/apps/shared/components/layout/UserMenu.tsx +6 -4
  119. package/apps/shared/components/mail/ConversationList.tsx +25 -10
  120. package/apps/shared/components/mail/ConversationThreadPane.tsx +33 -17
  121. package/apps/shared/components/mail/InviteCard.tsx +11 -9
  122. package/apps/shared/components/mail/LazyReadingPane.tsx +2 -2
  123. package/apps/shared/components/mail/MailAddress.tsx +1 -1
  124. package/apps/shared/components/mail/MailListToolbar.tsx +2 -2
  125. package/apps/shared/components/mail/MailSelectionBar.tsx +2 -2
  126. package/apps/shared/components/mail/MenuButton.tsx +1 -1
  127. package/apps/shared/components/mail/MessageDetailPane.tsx +69 -48
  128. package/apps/shared/components/mail/MoveToFolderDialog.tsx +8 -6
  129. package/apps/shared/components/mail/OutboxRowStatus.tsx +1 -1
  130. package/apps/shared/components/mail/PermanentDeleteDialog.tsx +2 -2
  131. package/apps/shared/components/mail/compose/ComposeContext.tsx +14 -3
  132. package/apps/shared/components/mail/compose/ComposeWindow.tsx +34 -30
  133. package/apps/shared/components/mail/compose/ComposeWindowPlaceholder.tsx +4 -4
  134. package/apps/shared/components/mail/compose/EmojiPicker.tsx +2 -2
  135. package/apps/shared/components/mail/compose/GifPicker.tsx +3 -3
  136. package/apps/shared/components/mail/compose/RecipientInput.tsx +1 -1
  137. package/apps/shared/components/mail/compose/ScheduleSendPicker.tsx +1 -1
  138. package/apps/shared/components/mail/compose/encryptionRequirement.ts +2 -2
  139. package/apps/shared/components/mail/compose/quotedBody.ts +5 -5
  140. package/apps/shared/components/mail/compose/recipients.ts +1 -1
  141. package/apps/shared/components/mail/invite/InviteRowChip.tsx +10 -14
  142. package/apps/shared/components/mail/invite/InviteRsvpPopover.tsx +11 -9
  143. package/apps/shared/components/mail/invite/InviteTimeline.tsx +1 -1
  144. package/apps/shared/components/mail/invite/ProposeTimeForm.tsx +2 -2
  145. package/apps/shared/components/mail/invite/inviteFormat.ts +2 -2
  146. package/apps/shared/components/mail/invite/inviteStore.ts +14 -6
  147. package/apps/shared/components/mail/labelMenu.tsx +9 -7
  148. package/apps/shared/components/mail/layout/MailShell.tsx +4 -4
  149. package/apps/shared/components/mail/listPreferences.ts +2 -2
  150. package/apps/shared/components/mail/pinnedSigners.ts +45 -19
  151. package/apps/shared/components/mail/reading/EncryptedBody.tsx +2 -2
  152. package/apps/shared/components/mail/reading/MessageBody.tsx +6 -6
  153. package/apps/shared/components/mail/reading/MessageCard.tsx +3 -3
  154. package/apps/shared/components/mail/reading/MessageSourceDialog.tsx +3 -3
  155. package/apps/shared/components/mail/reading/PendingMessageCard.tsx +1 -1
  156. package/apps/shared/components/mail/reading/bodyContent.ts +3 -3
  157. package/apps/shared/components/mail/reading/bodyHtml.ts +1 -1
  158. package/apps/shared/components/mail/reading/conversationPrint.ts +76 -0
  159. package/apps/shared/components/mail/reading/messageExport.ts +1 -1
  160. package/apps/shared/components/mail/reading/printMessage.ts +46 -9
  161. package/apps/shared/components/mail/reading/useMessageActions.ts +28 -21
  162. package/apps/shared/components/mail/unreadStyle.tsx +1 -1
  163. package/apps/shared/components/mail/verificationSeals.ts +16 -12
  164. package/apps/shared/components/mail/writableMailboxes.ts +14 -7
  165. package/apps/shared/components/rules/RuleBuilder.tsx +1 -1
  166. package/apps/shared/components/settings/SigningCertificateCard.tsx +4 -4
  167. package/apps/shared/components/settings/layout/SettingsShell.tsx +8 -6
  168. package/apps/shared/components/sharing/PrincipalListField.tsx +1 -1
  169. package/apps/shared/components/sharing/PrincipalPicker.tsx +1 -1
  170. package/apps/shared/components/sharing/PrincipalResolver.tsx +4 -4
  171. package/apps/shared/components/tasks/TasksSidebar.tsx +7 -5
  172. package/apps/shared/components/tasks/layout/TasksShell.tsx +9 -7
  173. package/apps/shared/keyboard/ShortcutsDialog.tsx +1 -1
  174. package/apps/shared/keyboard/keymap.ts +1 -0
  175. package/apps/shared/mail/decryptedMessages.ts +116 -0
  176. package/apps/shared/mail/findWellKnownFolderUid.ts +6 -4
  177. package/apps/shared/mail/folderCounts.ts +8 -4
  178. package/apps/shared/mail/folderOfType.ts +5 -3
  179. package/apps/shared/mail/folderTree.ts +1 -1
  180. package/apps/shared/mail/listSnapshots.ts +2 -2
  181. package/apps/shared/mail/messageReadState.ts +6 -5
  182. package/apps/shared/mail/newMailNotifications.ts +2 -2
  183. package/apps/shared/mail/outbox/composeBridge.ts +2 -2
  184. package/apps/shared/mail/outbox/outboxState.ts +1 -1
  185. package/apps/shared/mail/outbox/outgoingReplies.ts +2 -2
  186. package/apps/shared/mail/outbox/sendDecision.ts +2 -2
  187. package/apps/shared/mail/outbox/sendJob.ts +40 -35
  188. package/apps/shared/mail/outbox/sendOutcomes.ts +20 -15
  189. package/apps/shared/mail/outbox/useOutboxStatus.ts +5 -3
  190. package/apps/shared/mail/permanentDelete.ts +8 -7
  191. package/apps/shared/mail/primaryMailbox.ts +1 -1
  192. package/apps/shared/mail/reportNotices.ts +1 -1
  193. package/apps/shared/mail/senderBlocking.ts +36 -20
  194. package/apps/shared/mail/useMailConnection.ts +12 -10
  195. package/apps/shared/mail/useMailLiveUpdates.ts +3 -3
  196. package/apps/shared/mail/useMailboxUpdateAccess.ts +35 -11
  197. package/apps/shared/mail/useMarkMessageRead.ts +14 -7
  198. package/apps/shared/mail/useNewMailNotifications.ts +1 -1
  199. package/apps/shared/mail/usePermanentDelete.tsx +5 -3
  200. package/apps/shared/navigation/pageTitle.ts +1 -1
  201. package/apps/shared/notifications/NotificationCenter.tsx +1 -1
  202. package/apps/shared/notifications/NotificationHistoryDialog.tsx +2 -2
  203. package/apps/shared/notifications/apiErrors.ts +2 -2
  204. package/apps/shared/notifications/pushStatus.ts +1 -1
  205. package/apps/shared/notifications/systemErrors.ts +1 -1
  206. package/apps/shared/search/LocalIndexLifecycle.tsx +18 -12
  207. package/apps/shared/search/crossMailboxSearch.ts +3 -3
  208. package/apps/shared/search/localIndexBuilder.ts +24 -12
  209. package/apps/shared/search/localIndexKey.ts +1 -1
  210. package/apps/shared/search/localIndexRpcClient.ts +150 -30
  211. package/apps/shared/search/localIndexTransport.ts +84 -0
  212. package/apps/shared/search/localIndexWorker.ts +1 -1
  213. package/apps/shared/search/searchTier2.ts +3 -3
  214. package/apps/shared/signing/enrollmentTracker.ts +3 -3
  215. package/apps/shared/signing/enrollmentView.ts +1 -1
  216. package/apps/shared/signing/signingInfo.ts +1 -1
  217. package/apps/shared/signing/useSigningEnrollmentWatcher.ts +6 -4
  218. package/apps/shared/styles/app.css +14 -23
  219. package/apps/www/_layout.tsx +2 -2
  220. package/apps/www/calendar/index.tsx +20 -18
  221. package/apps/www/contacts/[uid].tsx +8 -6
  222. package/apps/www/contacts/index.tsx +19 -17
  223. package/apps/www/index.tsx +68 -48
  224. package/apps/www/messages/[uid].tsx +11 -9
  225. package/apps/www/settings/auto-reply/index.tsx +6 -4
  226. package/apps/www/settings/blocked-senders/index.tsx +9 -7
  227. package/apps/www/settings/encryption/index.tsx +38 -32
  228. package/apps/www/settings/filters/[uid].tsx +19 -14
  229. package/apps/www/settings/filters/_mailFilterRuleConfig.tsx +2 -2
  230. package/apps/www/settings/filters/index.tsx +4 -4
  231. package/apps/www/settings/filters/new/index.tsx +10 -8
  232. package/apps/www/settings/labels/index.tsx +12 -10
  233. package/apps/www/settings/privacy/index.tsx +18 -14
  234. package/apps/www/settings/profile/index.tsx +16 -11
  235. package/apps/www/settings/read-receipts/index.tsx +17 -12
  236. package/apps/www/settings/sharing/index.tsx +6 -6
  237. package/apps/www/settings/signatures/[uid].tsx +5 -5
  238. package/apps/www/settings/signatures/index.tsx +4 -4
  239. package/apps/www/settings/signatures/new/index.tsx +4 -4
  240. package/apps/www/settings/signatures/signatureDefaults.ts +1 -1
  241. package/apps/www/tasks/index.tsx +28 -23
  242. package/dist/apps/admin/_layout.d.ts +1 -1
  243. package/dist/apps/admin/_layout.js +1 -1
  244. package/dist/apps/admin/audit-log/index.d.ts +1 -1
  245. package/dist/apps/admin/audit-log/index.js +4 -4
  246. package/dist/apps/admin/branding/index.js +3 -3
  247. package/dist/apps/admin/data-requests/index.js +8 -8
  248. package/dist/apps/admin/distribution-lists/[uid].js +3 -3
  249. package/dist/apps/admin/distribution-lists/index.js +4 -4
  250. package/dist/apps/admin/distribution-lists/new/index.js +5 -5
  251. package/dist/apps/admin/domains/[uid].js +6 -6
  252. package/dist/apps/admin/domains/index.js +4 -4
  253. package/dist/apps/admin/domains/new/index.js +5 -5
  254. package/dist/apps/admin/encryption-policy/index.js +1 -1
  255. package/dist/apps/admin/escrow-scopes/[uid].d.ts +1 -1
  256. package/dist/apps/admin/escrow-scopes/[uid].js +7 -7
  257. package/dist/apps/admin/escrow-scopes/index.js +4 -4
  258. package/dist/apps/admin/escrow-scopes/new/index.js +5 -5
  259. package/dist/apps/admin/index.js +6 -6
  260. package/dist/apps/admin/ingest-queue/index.js +4 -4
  261. package/dist/apps/admin/mailbox-policy/index.js +1 -1
  262. package/dist/apps/admin/mailboxes/[uid].js +5 -5
  263. package/dist/apps/admin/quarantine/index.js +5 -5
  264. package/dist/apps/admin/retention-policy/index.js +3 -3
  265. package/dist/apps/admin/signing-certificates/index.js +5 -5
  266. package/dist/apps/admin/transport-rules/[uid].js +5 -5
  267. package/dist/apps/admin/transport-rules/_transportRuleConfig.d.ts +1 -1
  268. package/dist/apps/admin/transport-rules/_transportRuleConfig.js +2 -2
  269. package/dist/apps/admin/transport-rules/index.js +4 -4
  270. package/dist/apps/admin/transport-rules/new/index.js +5 -5
  271. package/dist/apps/escrow/_layout.d.ts +1 -1
  272. package/dist/apps/escrow/audit-log/index.d.ts +1 -1
  273. package/dist/apps/escrow/audit-log/index.js +4 -4
  274. package/dist/apps/escrow/index.js +4 -4
  275. package/dist/apps/escrow/matters/[uid].js +10 -10
  276. package/dist/apps/escrow/matters/new/index.js +6 -6
  277. package/dist/apps/shared/appearance/AppearanceForm.js +3 -3
  278. package/dist/apps/shared/appearance/AppearanceHead.js +1 -1
  279. package/dist/apps/shared/appearance/AppearanceProvider.d.ts +1 -1
  280. package/dist/apps/shared/appearance/AppearanceProvider.js +3 -3
  281. package/dist/apps/shared/appearance/appearanceCache.d.ts +1 -1
  282. package/dist/apps/shared/appearance/appearanceCache.js +1 -1
  283. package/dist/apps/shared/appearance/appearanceContext.d.ts +1 -1
  284. package/dist/apps/shared/appearance/theme.d.ts +1 -1
  285. package/dist/apps/shared/auth/adminAccess.js +1 -1
  286. package/dist/apps/shared/calendar/bookingPlugin.js +1 -1
  287. package/dist/apps/shared/calendar/calendarLiveUpdates.d.ts +1 -1
  288. package/dist/apps/shared/calendar/calendarReminders.d.ts +1 -1
  289. package/dist/apps/shared/calendar/useCalendarReminders.js +1 -1
  290. package/dist/apps/shared/components/admin/diagnostics/DiagnosticsManager.js +1 -1
  291. package/dist/apps/shared/components/admin/diagnostics/InstalledPlugins.d.ts +1 -1
  292. package/dist/apps/shared/components/admin/diagnostics/InstalledPlugins.js +2 -2
  293. package/dist/apps/shared/components/admin/diagnostics/LogsPanel.js +2 -2
  294. package/dist/apps/shared/components/admin/diagnostics/PackagesTable.js +1 -1
  295. package/dist/apps/shared/components/admin/diagnostics/RuntimePanel.js +1 -1
  296. package/dist/apps/shared/components/admin/diagnostics/SystemPanel.js +2 -2
  297. package/dist/apps/shared/components/admin/diagnostics/VersionsPanel.js +1 -1
  298. package/dist/apps/shared/components/admin/diagnostics/diagnosticsApi.js +1 -1
  299. package/dist/apps/shared/components/admin/diagnostics/format.js +1 -1
  300. package/dist/apps/shared/components/admin/diagnostics/logClient.js +1 -1
  301. package/dist/apps/shared/components/admin/distributionLists/MemberListCard.d.ts +1 -1
  302. package/dist/apps/shared/components/admin/distributionLists/MemberListCard.js +4 -4
  303. package/dist/apps/shared/components/admin/elevation.js +1 -1
  304. package/dist/apps/shared/components/admin/escrowScopes/EscrowScopeKeyAndHoldersFields.js +3 -3
  305. package/dist/apps/shared/components/admin/layout/AdminShell.d.ts +1 -1
  306. package/dist/apps/shared/components/admin/layout/AdminShell.js +7 -7
  307. package/dist/apps/shared/components/admin/mailboxes/EraseLeftoverDataDialog.d.ts +1 -1
  308. package/dist/apps/shared/components/admin/mailboxes/EraseLeftoverDataDialog.js +6 -6
  309. package/dist/apps/shared/components/admin/mailboxes/EscrowScopeCard.d.ts +1 -1
  310. package/dist/apps/shared/components/admin/mailboxes/EscrowScopeCard.js +10 -8
  311. package/dist/apps/shared/components/admin/mailboxes/LeftoverMailboxesSection.js +4 -4
  312. package/dist/apps/shared/components/admin/mailboxes/MailboxTable.d.ts +1 -1
  313. package/dist/apps/shared/components/admin/mailboxes/ResourceSettingsCard.d.ts +1 -1
  314. package/dist/apps/shared/components/admin/mailboxes/ResourceSettingsCard.js +7 -5
  315. package/dist/apps/shared/components/admin/mailboxes/ShareAccessCard.js +5 -5
  316. package/dist/apps/shared/components/admin/settings/BrandingForm.d.ts +1 -1
  317. package/dist/apps/shared/components/admin/settings/BrandingForm.js +5 -5
  318. package/dist/apps/shared/components/admin/settings/DomainDnsSetup.d.ts +1 -1
  319. package/dist/apps/shared/components/admin/settings/DomainDnsSetup.js +5 -5
  320. package/dist/apps/shared/components/admin/settings/EncryptionPolicyForm.d.ts +1 -1
  321. package/dist/apps/shared/components/admin/settings/EncryptionPolicyForm.js +4 -4
  322. package/dist/apps/shared/components/admin/settings/LoadedSettingsForm.js +2 -2
  323. package/dist/apps/shared/components/admin/settings/MailboxCreateForm.d.ts +1 -1
  324. package/dist/apps/shared/components/admin/settings/MailboxCreateForm.js +14 -12
  325. package/dist/apps/shared/components/admin/settings/MailboxPolicyForm.d.ts +1 -1
  326. package/dist/apps/shared/components/admin/settings/MailboxPolicyForm.js +4 -4
  327. package/dist/apps/shared/components/admin/settings/PluginsManager.js +5 -5
  328. package/dist/apps/shared/components/admin/settings/RetentionPolicyForm.d.ts +1 -1
  329. package/dist/apps/shared/components/admin/settings/RetentionPolicyForm.js +5 -5
  330. package/dist/apps/shared/components/admin/setup/EscrowSetupStep.js +7 -7
  331. package/dist/apps/shared/components/admin/setup/SetupWizard.d.ts +4 -4
  332. package/dist/apps/shared/components/admin/setup/SetupWizard.js +27 -23
  333. package/dist/apps/shared/components/admin/signOut.js +1 -1
  334. package/dist/apps/shared/components/admin/usePagedList.js +2 -2
  335. package/dist/apps/shared/components/calendar/AppointmentQuickForm.js +3 -3
  336. package/dist/apps/shared/components/calendar/CalendarListSidebar.d.ts +1 -1
  337. package/dist/apps/shared/components/calendar/CalendarListSidebar.js +2 -2
  338. package/dist/apps/shared/components/calendar/DescriptionEditor.js +1 -1
  339. package/dist/apps/shared/components/calendar/EventDescriptionView.js +1 -1
  340. package/dist/apps/shared/components/calendar/EventDetails.d.ts +2 -2
  341. package/dist/apps/shared/components/calendar/EventDetails.js +16 -14
  342. package/dist/apps/shared/components/calendar/EventEditor.d.ts +2 -2
  343. package/dist/apps/shared/components/calendar/EventEditor.js +22 -20
  344. package/dist/apps/shared/components/calendar/EventExpandedForm.js +2 -2
  345. package/dist/apps/shared/components/calendar/EventFormParts.d.ts +1 -1
  346. package/dist/apps/shared/components/calendar/EventFormParts.js +1 -1
  347. package/dist/apps/shared/components/calendar/EventModal.d.ts +2 -2
  348. package/dist/apps/shared/components/calendar/EventModal.js +3 -3
  349. package/dist/apps/shared/components/calendar/EventQuickForm.js +3 -3
  350. package/dist/apps/shared/components/calendar/EventShell.js +1 -1
  351. package/dist/apps/shared/components/calendar/FindATime.js +6 -4
  352. package/dist/apps/shared/components/calendar/GuestInput.d.ts +2 -2
  353. package/dist/apps/shared/components/calendar/MonthView.d.ts +1 -1
  354. package/dist/apps/shared/components/calendar/MonthView.js +1 -1
  355. package/dist/apps/shared/components/calendar/QuickCreateFaces.js +1 -1
  356. package/dist/apps/shared/components/calendar/QuickFaceFrame.js +1 -1
  357. package/dist/apps/shared/components/calendar/RecurrenceEditor.d.ts +1 -1
  358. package/dist/apps/shared/components/calendar/RecurrenceEditor.js +1 -1
  359. package/dist/apps/shared/components/calendar/RequestChangeForm.js +8 -6
  360. package/dist/apps/shared/components/calendar/ResourcePicker.d.ts +1 -1
  361. package/dist/apps/shared/components/calendar/ResourcePicker.js +7 -5
  362. package/dist/apps/shared/components/calendar/SplitDayView.d.ts +1 -1
  363. package/dist/apps/shared/components/calendar/TaskQuickForm.d.ts +1 -1
  364. package/dist/apps/shared/components/calendar/TaskQuickForm.js +9 -7
  365. package/dist/apps/shared/components/calendar/TimeGridView.d.ts +1 -1
  366. package/dist/apps/shared/components/calendar/TimeGridView.js +2 -2
  367. package/dist/apps/shared/components/calendar/allDay.d.ts +2 -2
  368. package/dist/apps/shared/components/calendar/allDay.js +1 -1
  369. package/dist/apps/shared/components/calendar/eventDialogFields.d.ts +2 -2
  370. package/dist/apps/shared/components/calendar/eventDialogFields.js +2 -2
  371. package/dist/apps/shared/components/calendar/eventForm.d.ts +3 -3
  372. package/dist/apps/shared/components/calendar/eventFormat.d.ts +1 -1
  373. package/dist/apps/shared/components/calendar/eventFormat.js +2 -2
  374. package/dist/apps/shared/components/calendar/findTimeGrid.d.ts +1 -1
  375. package/dist/apps/shared/components/calendar/findTimeGrid.js +1 -1
  376. package/dist/apps/shared/components/calendar/layout/CalendarShell.d.ts +1 -1
  377. package/dist/apps/shared/components/calendar/layout/CalendarShell.js +11 -9
  378. package/dist/apps/shared/components/contacts/ContactDetailPane.d.ts +1 -1
  379. package/dist/apps/shared/components/contacts/ContactDetailPane.js +2 -2
  380. package/dist/apps/shared/components/contacts/ContactForm.d.ts +2 -2
  381. package/dist/apps/shared/components/contacts/ContactForm.js +12 -8
  382. package/dist/apps/shared/components/contacts/ContactsSidebar.d.ts +1 -1
  383. package/dist/apps/shared/components/contacts/ContactsSidebar.js +7 -5
  384. package/dist/apps/shared/components/contacts/KeyChangeReview.d.ts +1 -1
  385. package/dist/apps/shared/components/contacts/KeyChangeReview.js +5 -5
  386. package/dist/apps/shared/components/contacts/contactKeys.d.ts +2 -2
  387. package/dist/apps/shared/components/contacts/contactKeys.js +2 -2
  388. package/dist/apps/shared/components/contacts/layout/ContactsShell.d.ts +1 -1
  389. package/dist/apps/shared/components/contacts/layout/ContactsShell.js +9 -7
  390. package/dist/apps/shared/components/escrow/layout/EscrowShell.js +6 -6
  391. package/dist/apps/shared/components/forms/StringListField.js +1 -1
  392. package/dist/apps/shared/components/layout/AppShell.d.ts +2 -2
  393. package/dist/apps/shared/components/layout/AppShell.js +11 -9
  394. package/dist/apps/shared/components/layout/BrandingChrome.d.ts +1 -1
  395. package/dist/apps/shared/components/layout/KeyEnrollmentGate.d.ts +1 -1
  396. package/dist/apps/shared/components/layout/KeyEnrollmentGate.js +9 -9
  397. package/dist/apps/shared/components/layout/MailboxProvisioning.js +8 -6
  398. package/dist/apps/shared/components/layout/RecoveryCodeUnlock.d.ts +1 -1
  399. package/dist/apps/shared/components/layout/RecoveryCodeUnlock.js +9 -9
  400. package/dist/apps/shared/components/layout/UnlockPromptProvider.d.ts +2 -2
  401. package/dist/apps/shared/components/layout/UnlockPromptProvider.js +5 -5
  402. package/dist/apps/shared/components/layout/UserMenu.js +6 -4
  403. package/dist/apps/shared/components/mail/ConversationList.d.ts +2 -2
  404. package/dist/apps/shared/components/mail/ConversationList.js +23 -8
  405. package/dist/apps/shared/components/mail/ConversationThreadPane.d.ts +3 -3
  406. package/dist/apps/shared/components/mail/ConversationThreadPane.js +19 -13
  407. package/dist/apps/shared/components/mail/InviteCard.js +10 -8
  408. package/dist/apps/shared/components/mail/LazyReadingPane.js +2 -2
  409. package/dist/apps/shared/components/mail/MailAddress.d.ts +1 -1
  410. package/dist/apps/shared/components/mail/MailAddress.js +1 -1
  411. package/dist/apps/shared/components/mail/MailListToolbar.d.ts +2 -2
  412. package/dist/apps/shared/components/mail/MailSelectionBar.d.ts +2 -2
  413. package/dist/apps/shared/components/mail/MenuButton.js +1 -1
  414. package/dist/apps/shared/components/mail/MessageDetailPane.d.ts +3 -3
  415. package/dist/apps/shared/components/mail/MessageDetailPane.js +61 -46
  416. package/dist/apps/shared/components/mail/MoveToFolderDialog.d.ts +1 -1
  417. package/dist/apps/shared/components/mail/MoveToFolderDialog.js +8 -6
  418. package/dist/apps/shared/components/mail/OutboxRowStatus.d.ts +1 -1
  419. package/dist/apps/shared/components/mail/PermanentDeleteDialog.js +2 -2
  420. package/dist/apps/shared/components/mail/compose/ComposeContext.d.ts +10 -1
  421. package/dist/apps/shared/components/mail/compose/ComposeContext.js +4 -2
  422. package/dist/apps/shared/components/mail/compose/ComposeWindow.js +34 -30
  423. package/dist/apps/shared/components/mail/compose/ComposeWindowPlaceholder.js +4 -4
  424. package/dist/apps/shared/components/mail/compose/EmojiPicker.js +2 -2
  425. package/dist/apps/shared/components/mail/compose/GifPicker.js +3 -3
  426. package/dist/apps/shared/components/mail/compose/RecipientInput.d.ts +1 -1
  427. package/dist/apps/shared/components/mail/compose/RecipientInput.js +1 -1
  428. package/dist/apps/shared/components/mail/compose/ScheduleSendPicker.js +1 -1
  429. package/dist/apps/shared/components/mail/compose/encryptionRequirement.d.ts +2 -2
  430. package/dist/apps/shared/components/mail/compose/encryptionRequirement.js +1 -1
  431. package/dist/apps/shared/components/mail/compose/quotedBody.d.ts +3 -3
  432. package/dist/apps/shared/components/mail/compose/quotedBody.js +3 -3
  433. package/dist/apps/shared/components/mail/compose/recipients.d.ts +1 -1
  434. package/dist/apps/shared/components/mail/invite/InviteRowChip.d.ts +3 -3
  435. package/dist/apps/shared/components/mail/invite/InviteRowChip.js +7 -9
  436. package/dist/apps/shared/components/mail/invite/InviteRsvpPopover.d.ts +2 -2
  437. package/dist/apps/shared/components/mail/invite/InviteRsvpPopover.js +11 -9
  438. package/dist/apps/shared/components/mail/invite/InviteTimeline.d.ts +1 -1
  439. package/dist/apps/shared/components/mail/invite/ProposeTimeForm.d.ts +1 -1
  440. package/dist/apps/shared/components/mail/invite/ProposeTimeForm.js +1 -1
  441. package/dist/apps/shared/components/mail/invite/inviteFormat.d.ts +2 -2
  442. package/dist/apps/shared/components/mail/invite/inviteStore.d.ts +9 -3
  443. package/dist/apps/shared/components/mail/invite/inviteStore.js +13 -6
  444. package/dist/apps/shared/components/mail/labelMenu.d.ts +1 -1
  445. package/dist/apps/shared/components/mail/labelMenu.js +9 -7
  446. package/dist/apps/shared/components/mail/layout/MailShell.d.ts +1 -1
  447. package/dist/apps/shared/components/mail/layout/MailShell.js +3 -3
  448. package/dist/apps/shared/components/mail/listPreferences.d.ts +2 -2
  449. package/dist/apps/shared/components/mail/listPreferences.js +1 -1
  450. package/dist/apps/shared/components/mail/pinnedSigners.d.ts +12 -5
  451. package/dist/apps/shared/components/mail/pinnedSigners.js +37 -18
  452. package/dist/apps/shared/components/mail/reading/EncryptedBody.js +2 -2
  453. package/dist/apps/shared/components/mail/reading/MessageBody.d.ts +2 -2
  454. package/dist/apps/shared/components/mail/reading/MessageBody.js +4 -4
  455. package/dist/apps/shared/components/mail/reading/MessageCard.d.ts +1 -1
  456. package/dist/apps/shared/components/mail/reading/MessageCard.js +2 -2
  457. package/dist/apps/shared/components/mail/reading/MessageSourceDialog.js +3 -3
  458. package/dist/apps/shared/components/mail/reading/PendingMessageCard.js +1 -1
  459. package/dist/apps/shared/components/mail/reading/bodyContent.d.ts +2 -2
  460. package/dist/apps/shared/components/mail/reading/bodyContent.js +2 -2
  461. package/dist/apps/shared/components/mail/reading/bodyHtml.js +1 -1
  462. package/dist/apps/shared/components/mail/reading/conversationPrint.d.ts +15 -0
  463. package/dist/apps/shared/components/mail/reading/conversationPrint.js +69 -0
  464. package/dist/apps/shared/components/mail/reading/messageExport.js +1 -1
  465. package/dist/apps/shared/components/mail/reading/printMessage.d.ts +9 -3
  466. package/dist/apps/shared/components/mail/reading/printMessage.js +33 -6
  467. package/dist/apps/shared/components/mail/reading/useMessageActions.d.ts +1 -1
  468. package/dist/apps/shared/components/mail/reading/useMessageActions.js +18 -16
  469. package/dist/apps/shared/components/mail/unreadStyle.d.ts +1 -1
  470. package/dist/apps/shared/components/mail/verificationSeals.d.ts +27 -6
  471. package/dist/apps/shared/components/mail/verificationSeals.js +15 -11
  472. package/dist/apps/shared/components/mail/writableMailboxes.d.ts +8 -3
  473. package/dist/apps/shared/components/mail/writableMailboxes.js +12 -6
  474. package/dist/apps/shared/components/rules/RuleBuilder.js +1 -1
  475. package/dist/apps/shared/components/settings/SigningCertificateCard.d.ts +1 -1
  476. package/dist/apps/shared/components/settings/SigningCertificateCard.js +3 -3
  477. package/dist/apps/shared/components/settings/layout/SettingsShell.d.ts +1 -1
  478. package/dist/apps/shared/components/settings/layout/SettingsShell.js +8 -6
  479. package/dist/apps/shared/components/sharing/PrincipalListField.d.ts +1 -1
  480. package/dist/apps/shared/components/sharing/PrincipalPicker.d.ts +1 -1
  481. package/dist/apps/shared/components/sharing/PrincipalPicker.js +1 -1
  482. package/dist/apps/shared/components/sharing/PrincipalResolver.d.ts +1 -1
  483. package/dist/apps/shared/components/sharing/PrincipalResolver.js +3 -3
  484. package/dist/apps/shared/components/tasks/TasksSidebar.d.ts +1 -1
  485. package/dist/apps/shared/components/tasks/TasksSidebar.js +7 -5
  486. package/dist/apps/shared/components/tasks/layout/TasksShell.d.ts +1 -1
  487. package/dist/apps/shared/components/tasks/layout/TasksShell.js +9 -7
  488. package/dist/apps/shared/keyboard/ShortcutsDialog.js +1 -1
  489. package/dist/apps/shared/keyboard/keymap.d.ts +6 -0
  490. package/dist/apps/shared/keyboard/keymap.js +1 -0
  491. package/dist/apps/shared/mail/decryptedMessages.d.ts +27 -0
  492. package/dist/apps/shared/mail/decryptedMessages.js +97 -0
  493. package/dist/apps/shared/mail/findWellKnownFolderUid.d.ts +5 -3
  494. package/dist/apps/shared/mail/findWellKnownFolderUid.js +5 -4
  495. package/dist/apps/shared/mail/folderCounts.d.ts +1 -1
  496. package/dist/apps/shared/mail/folderCounts.js +6 -4
  497. package/dist/apps/shared/mail/folderOfType.d.ts +3 -2
  498. package/dist/apps/shared/mail/folderOfType.js +4 -4
  499. package/dist/apps/shared/mail/folderTree.d.ts +1 -1
  500. package/dist/apps/shared/mail/listSnapshots.d.ts +2 -2
  501. package/dist/apps/shared/mail/messageReadState.d.ts +4 -3
  502. package/dist/apps/shared/mail/messageReadState.js +5 -5
  503. package/dist/apps/shared/mail/newMailNotifications.d.ts +1 -1
  504. package/dist/apps/shared/mail/newMailNotifications.js +1 -1
  505. package/dist/apps/shared/mail/outbox/composeBridge.d.ts +2 -2
  506. package/dist/apps/shared/mail/outbox/outboxState.d.ts +1 -1
  507. package/dist/apps/shared/mail/outbox/outgoingReplies.d.ts +2 -2
  508. package/dist/apps/shared/mail/outbox/sendDecision.d.ts +2 -2
  509. package/dist/apps/shared/mail/outbox/sendDecision.js +1 -1
  510. package/dist/apps/shared/mail/outbox/sendJob.d.ts +10 -6
  511. package/dist/apps/shared/mail/outbox/sendJob.js +39 -35
  512. package/dist/apps/shared/mail/outbox/sendOutcomes.d.ts +6 -3
  513. package/dist/apps/shared/mail/outbox/sendOutcomes.js +19 -15
  514. package/dist/apps/shared/mail/outbox/useOutboxStatus.js +5 -3
  515. package/dist/apps/shared/mail/permanentDelete.d.ts +4 -3
  516. package/dist/apps/shared/mail/permanentDelete.js +8 -8
  517. package/dist/apps/shared/mail/primaryMailbox.d.ts +1 -1
  518. package/dist/apps/shared/mail/primaryMailbox.js +1 -1
  519. package/dist/apps/shared/mail/reportNotices.d.ts +1 -1
  520. package/dist/apps/shared/mail/senderBlocking.d.ts +5 -4
  521. package/dist/apps/shared/mail/senderBlocking.js +19 -16
  522. package/dist/apps/shared/mail/useMailConnection.d.ts +1 -1
  523. package/dist/apps/shared/mail/useMailConnection.js +12 -10
  524. package/dist/apps/shared/mail/useMailLiveUpdates.d.ts +2 -2
  525. package/dist/apps/shared/mail/useMailLiveUpdates.js +2 -2
  526. package/dist/apps/shared/mail/useMailboxUpdateAccess.d.ts +3 -2
  527. package/dist/apps/shared/mail/useMailboxUpdateAccess.js +31 -10
  528. package/dist/apps/shared/mail/useMarkMessageRead.d.ts +1 -1
  529. package/dist/apps/shared/mail/useMarkMessageRead.js +5 -3
  530. package/dist/apps/shared/mail/useNewMailNotifications.d.ts +1 -1
  531. package/dist/apps/shared/mail/usePermanentDelete.d.ts +1 -1
  532. package/dist/apps/shared/mail/usePermanentDelete.js +4 -2
  533. package/dist/apps/shared/navigation/pageTitle.d.ts +1 -1
  534. package/dist/apps/shared/notifications/NotificationCenter.js +1 -1
  535. package/dist/apps/shared/notifications/NotificationHistoryDialog.js +2 -2
  536. package/dist/apps/shared/notifications/apiErrors.js +2 -2
  537. package/dist/apps/shared/notifications/pushStatus.js +1 -1
  538. package/dist/apps/shared/notifications/systemErrors.js +1 -1
  539. package/dist/apps/shared/search/LocalIndexLifecycle.d.ts +2 -2
  540. package/dist/apps/shared/search/LocalIndexLifecycle.js +15 -10
  541. package/dist/apps/shared/search/crossMailboxSearch.d.ts +1 -1
  542. package/dist/apps/shared/search/crossMailboxSearch.js +2 -2
  543. package/dist/apps/shared/search/localIndexBuilder.d.ts +4 -3
  544. package/dist/apps/shared/search/localIndexBuilder.js +15 -12
  545. package/dist/apps/shared/search/localIndexKey.js +1 -1
  546. package/dist/apps/shared/search/localIndexRpcClient.d.ts +43 -31
  547. package/dist/apps/shared/search/localIndexRpcClient.js +113 -20
  548. package/dist/apps/shared/search/localIndexTransport.d.ts +77 -0
  549. package/dist/apps/shared/search/localIndexTransport.js +1 -0
  550. package/dist/apps/shared/search/localIndexWorker.d.ts +1 -1
  551. package/dist/apps/shared/search/searchTier2.d.ts +3 -3
  552. package/dist/apps/shared/signing/enrollmentTracker.d.ts +1 -1
  553. package/dist/apps/shared/signing/enrollmentTracker.js +3 -3
  554. package/dist/apps/shared/signing/enrollmentView.d.ts +1 -1
  555. package/dist/apps/shared/signing/signingInfo.d.ts +1 -1
  556. package/dist/apps/shared/signing/signingInfo.js +1 -1
  557. package/dist/apps/shared/signing/useSigningEnrollmentWatcher.d.ts +1 -1
  558. package/dist/apps/shared/signing/useSigningEnrollmentWatcher.js +5 -3
  559. package/dist/apps/shared/styles/app.css +14 -23
  560. package/dist/apps/www/_layout.d.ts +1 -1
  561. package/dist/apps/www/_layout.js +1 -1
  562. package/dist/apps/www/calendar/index.d.ts +1 -1
  563. package/dist/apps/www/calendar/index.js +20 -18
  564. package/dist/apps/www/contacts/[uid].d.ts +1 -1
  565. package/dist/apps/www/contacts/[uid].js +8 -6
  566. package/dist/apps/www/contacts/index.d.ts +1 -1
  567. package/dist/apps/www/contacts/index.js +19 -17
  568. package/dist/apps/www/index.d.ts +1 -1
  569. package/dist/apps/www/index.js +64 -50
  570. package/dist/apps/www/messages/[uid].d.ts +1 -1
  571. package/dist/apps/www/messages/[uid].js +11 -9
  572. package/dist/apps/www/settings/appearance/index.d.ts +1 -1
  573. package/dist/apps/www/settings/auto-reply/index.d.ts +1 -1
  574. package/dist/apps/www/settings/auto-reply/index.js +6 -4
  575. package/dist/apps/www/settings/blocked-senders/index.d.ts +1 -1
  576. package/dist/apps/www/settings/blocked-senders/index.js +6 -4
  577. package/dist/apps/www/settings/encryption/index.d.ts +1 -1
  578. package/dist/apps/www/settings/encryption/index.js +31 -29
  579. package/dist/apps/www/settings/filters/[uid].d.ts +1 -1
  580. package/dist/apps/www/settings/filters/[uid].js +11 -9
  581. package/dist/apps/www/settings/filters/_mailFilterRuleConfig.d.ts +2 -2
  582. package/dist/apps/www/settings/filters/index.d.ts +1 -1
  583. package/dist/apps/www/settings/filters/index.js +4 -4
  584. package/dist/apps/www/settings/filters/new/index.d.ts +1 -1
  585. package/dist/apps/www/settings/filters/new/index.js +10 -8
  586. package/dist/apps/www/settings/labels/index.d.ts +1 -1
  587. package/dist/apps/www/settings/labels/index.js +12 -10
  588. package/dist/apps/www/settings/privacy/index.d.ts +1 -1
  589. package/dist/apps/www/settings/privacy/index.js +18 -14
  590. package/dist/apps/www/settings/profile/index.d.ts +1 -1
  591. package/dist/apps/www/settings/profile/index.js +7 -5
  592. package/dist/apps/www/settings/read-receipts/index.d.ts +1 -1
  593. package/dist/apps/www/settings/read-receipts/index.js +5 -3
  594. package/dist/apps/www/settings/sharing/index.d.ts +1 -1
  595. package/dist/apps/www/settings/sharing/index.js +6 -6
  596. package/dist/apps/www/settings/signatures/[uid].d.ts +1 -1
  597. package/dist/apps/www/settings/signatures/[uid].js +5 -5
  598. package/dist/apps/www/settings/signatures/index.d.ts +1 -1
  599. package/dist/apps/www/settings/signatures/index.js +4 -4
  600. package/dist/apps/www/settings/signatures/new/index.d.ts +1 -1
  601. package/dist/apps/www/settings/signatures/new/index.js +4 -4
  602. package/dist/apps/www/settings/signatures/signatureDefaults.d.ts +1 -1
  603. package/dist/apps/www/settings/signatures/signatureDefaults.js +1 -1
  604. package/dist/apps/www/tasks/index.d.ts +1 -1
  605. package/dist/apps/www/tasks/index.js +17 -15
  606. package/dist/lib/admin/auditLogApi.d.ts +32 -0
  607. package/dist/lib/admin/auditLogApi.js +27 -0
  608. package/dist/lib/admin/distributionListsApi.d.ts +47 -0
  609. package/dist/lib/admin/distributionListsApi.js +34 -0
  610. package/dist/lib/admin/domainsApi.d.ts +75 -0
  611. package/dist/lib/admin/domainsApi.js +44 -0
  612. package/dist/lib/admin/escrowAccessRequestsApi.d.ts +79 -0
  613. package/dist/lib/admin/escrowAccessRequestsApi.js +46 -0
  614. package/dist/lib/admin/escrowAuditLogApi.d.ts +66 -0
  615. package/dist/lib/admin/escrowAuditLogApi.js +31 -0
  616. package/dist/lib/admin/escrowScopesApi.d.ts +78 -0
  617. package/dist/lib/admin/escrowScopesApi.js +50 -0
  618. package/dist/lib/admin/leftoverMailboxApi.d.ts +73 -0
  619. package/dist/lib/admin/leftoverMailboxApi.js +67 -0
  620. package/dist/lib/admin/mailboxPolicyApi.d.ts +27 -0
  621. package/dist/lib/admin/mailboxPolicyApi.js +21 -0
  622. package/dist/lib/admin/matterExportApi.d.ts +40 -0
  623. package/dist/lib/admin/matterExportApi.js +39 -0
  624. package/dist/lib/admin/matterSearchApi.d.ts +20 -0
  625. package/dist/lib/admin/matterSearchApi.js +27 -0
  626. package/dist/lib/admin/mattersApi.d.ts +56 -0
  627. package/dist/lib/admin/mattersApi.js +40 -0
  628. package/dist/lib/admin/pluginsApi.d.ts +265 -0
  629. package/dist/lib/admin/pluginsApi.js +102 -0
  630. package/dist/lib/admin/retentionPolicyApi.d.ts +32 -0
  631. package/dist/lib/admin/retentionPolicyApi.js +29 -0
  632. package/dist/lib/admin/setupApi.d.ts +23 -0
  633. package/dist/lib/admin/setupApi.js +26 -0
  634. package/dist/lib/admin/transportRulesApi.d.ts +66 -0
  635. package/dist/lib/admin/transportRulesApi.js +43 -0
  636. package/dist/lib/appearance/preferencesApi.d.ts +128 -0
  637. package/dist/lib/appearance/preferencesApi.js +257 -0
  638. package/dist/lib/auth/profileApi.d.ts +33 -0
  639. package/dist/lib/auth/profileApi.js +52 -0
  640. package/dist/lib/auth/session.d.ts +70 -0
  641. package/dist/lib/auth/session.js +210 -0
  642. package/dist/lib/branding/brandingApi.d.ts +47 -0
  643. package/dist/lib/branding/brandingApi.js +61 -0
  644. package/dist/lib/branding/useBranding.d.ts +23 -0
  645. package/dist/lib/branding/useBranding.js +65 -0
  646. package/dist/lib/calendar/calendarApi.d.ts +230 -0
  647. package/dist/lib/calendar/calendarApi.js +106 -0
  648. package/dist/lib/calendar/calendarColors.d.ts +18 -0
  649. package/dist/lib/calendar/calendarColors.js +39 -0
  650. package/dist/lib/calendar/calendarDragIds.d.ts +42 -0
  651. package/dist/lib/calendar/calendarDragIds.js +92 -0
  652. package/dist/lib/calendar/calendarMutations.d.ts +68 -0
  653. package/dist/lib/calendar/calendarMutations.js +190 -0
  654. package/dist/lib/calendar/eventDescription.d.ts +43 -0
  655. package/dist/lib/calendar/eventDescription.js +195 -0
  656. package/dist/lib/calendar/freeBusyApi.d.ts +100 -0
  657. package/dist/lib/calendar/freeBusyApi.js +119 -0
  658. package/dist/lib/calendar/inviteApi.d.ts +121 -0
  659. package/dist/lib/calendar/inviteApi.js +54 -0
  660. package/dist/lib/calendar/recurrence.d.ts +60 -0
  661. package/dist/lib/calendar/recurrence.js +225 -0
  662. package/dist/lib/components/avatar/ContactAvatar.d.ts +8 -0
  663. package/dist/lib/components/avatar/ContactAvatar.js +26 -0
  664. package/dist/lib/components/buttons/Button.d.ts +9 -0
  665. package/dist/lib/components/buttons/Button.js +14 -0
  666. package/dist/lib/components/buttons/CopyButton.d.ts +18 -0
  667. package/dist/lib/components/buttons/CopyButton.js +14 -0
  668. package/dist/lib/components/feedback/Alert.d.ts +4 -0
  669. package/dist/lib/components/feedback/Alert.js +4 -0
  670. package/dist/lib/components/feedback/Skeleton.d.ts +21 -0
  671. package/dist/lib/components/feedback/Skeleton.js +14 -0
  672. package/dist/lib/components/forms/FormField.d.ts +8 -0
  673. package/dist/lib/components/forms/FormField.js +5 -0
  674. package/dist/lib/components/navigation/BottomTabBar.d.ts +27 -0
  675. package/dist/lib/components/navigation/BottomTabBar.js +32 -0
  676. package/dist/lib/components/overlays/Drawer.d.ts +20 -0
  677. package/dist/lib/components/overlays/Drawer.js +27 -0
  678. package/dist/lib/components/overlays/Modal.d.ts +17 -0
  679. package/dist/lib/components/overlays/Modal.js +25 -0
  680. package/dist/lib/components/overlays/PopoverPortal.d.ts +23 -0
  681. package/dist/lib/components/overlays/PopoverPortal.js +53 -0
  682. package/dist/lib/components/overlays/overlayStack.d.ts +31 -0
  683. package/dist/lib/components/overlays/overlayStack.js +143 -0
  684. package/dist/lib/components/pickers/MiniDatePicker.d.ts +13 -0
  685. package/dist/lib/components/pickers/MiniDatePicker.js +42 -0
  686. package/dist/lib/contacts/contactsApi.d.ts +174 -0
  687. package/dist/lib/contacts/contactsApi.js +139 -0
  688. package/dist/lib/contacts/vcard.d.ts +23 -0
  689. package/dist/lib/contacts/vcard.js +179 -0
  690. package/dist/lib/crypto/composeSecurity.d.ts +67 -0
  691. package/dist/lib/crypto/composeSecurity.js +93 -0
  692. package/dist/lib/crypto/encoding.d.ts +9 -0
  693. package/dist/lib/crypto/encoding.js +32 -0
  694. package/dist/lib/crypto/escrowKeys.d.ts +25 -0
  695. package/dist/lib/crypto/escrowKeys.js +59 -0
  696. package/dist/lib/crypto/idleTimeout.d.ts +16 -0
  697. package/dist/lib/crypto/idleTimeout.js +47 -0
  698. package/dist/lib/crypto/keySession.d.ts +159 -0
  699. package/dist/lib/crypto/keySession.js +367 -0
  700. package/dist/lib/crypto/keys.d.ts +50 -0
  701. package/dist/lib/crypto/keys.js +89 -0
  702. package/dist/lib/crypto/keyvaultApi.d.ts +394 -0
  703. package/dist/lib/crypto/keyvaultApi.js +350 -0
  704. package/dist/lib/crypto/masterKey.d.ts +59 -0
  705. package/dist/lib/crypto/masterKey.js +104 -0
  706. package/dist/lib/crypto/masterKeyWraps.d.ts +108 -0
  707. package/dist/lib/crypto/masterKeyWraps.js +228 -0
  708. package/dist/lib/crypto/messageSecurity.d.ts +248 -0
  709. package/dist/lib/crypto/messageSecurity.js +367 -0
  710. package/dist/lib/crypto/mime.d.ts +143 -0
  711. package/dist/lib/crypto/mime.js +504 -0
  712. package/dist/lib/crypto/passkeyUnlock.d.ts +20 -0
  713. package/dist/lib/crypto/passkeyUnlock.js +79 -0
  714. package/dist/lib/crypto/passwordUnlock.d.ts +39 -0
  715. package/dist/lib/crypto/passwordUnlock.js +73 -0
  716. package/dist/lib/crypto/recoveryCode.d.ts +28 -0
  717. package/dist/lib/crypto/recoveryCode.js +86 -0
  718. package/dist/lib/crypto/signingProviderApi.d.ts +95 -0
  719. package/dist/lib/crypto/signingProviderApi.js +60 -0
  720. package/dist/lib/crypto/smime.d.ts +128 -0
  721. package/dist/lib/crypto/smime.js +402 -0
  722. package/dist/lib/crypto/smimeMessage.d.ts +132 -0
  723. package/dist/lib/crypto/smimeMessage.js +341 -0
  724. package/dist/lib/crypto/useIdleKeyTimeout.d.ts +10 -0
  725. package/dist/lib/crypto/useIdleKeyTimeout.js +163 -0
  726. package/dist/lib/crypto/verificationSeal.d.ts +56 -0
  727. package/dist/lib/crypto/verificationSeal.js +220 -0
  728. package/dist/lib/mail/compose/composeQuoting.d.ts +88 -0
  729. package/dist/lib/mail/compose/composeQuoting.js +204 -0
  730. package/dist/lib/mail/compose/emojiData.d.ts +9 -0
  731. package/dist/lib/mail/compose/emojiData.js +18 -0
  732. package/dist/lib/mail/compose/giphyApi.d.ts +17 -0
  733. package/dist/lib/mail/compose/giphyApi.js +20 -0
  734. package/dist/lib/mail/conversationsApi.d.ts +80 -0
  735. package/dist/lib/mail/conversationsApi.js +44 -0
  736. package/dist/lib/mail/dataExportApi.d.ts +50 -0
  737. package/dist/lib/mail/dataExportApi.js +40 -0
  738. package/dist/lib/mail/directoryApi.d.ts +49 -0
  739. package/dist/lib/mail/directoryApi.js +101 -0
  740. package/dist/lib/mail/erasureRequestApi.d.ts +45 -0
  741. package/dist/lib/mail/erasureRequestApi.js +43 -0
  742. package/dist/lib/mail/flaggedMessages.d.ts +22 -0
  743. package/dist/lib/mail/flaggedMessages.js +73 -0
  744. package/dist/lib/mail/focusedInboxOverridesApi.d.ts +37 -0
  745. package/dist/lib/mail/focusedInboxOverridesApi.js +34 -0
  746. package/dist/lib/mail/labelsApi.d.ts +47 -0
  747. package/dist/lib/mail/labelsApi.js +38 -0
  748. package/dist/lib/mail/mailAddress.d.ts +27 -0
  749. package/dist/lib/mail/mailAddress.js +54 -0
  750. package/dist/lib/mail/mailApi.d.ts +850 -0
  751. package/dist/lib/mail/mailApi.js +602 -0
  752. package/dist/lib/mail/mailDetailHooks.d.ts +10 -0
  753. package/dist/lib/mail/mailDetailHooks.js +53 -0
  754. package/dist/lib/mail/mailFilterRulesApi.d.ts +76 -0
  755. package/dist/lib/mail/mailFilterRulesApi.js +45 -0
  756. package/dist/lib/mail/mailSignaturesApi.d.ts +49 -0
  757. package/dist/lib/mail/mailSignaturesApi.js +42 -0
  758. package/dist/lib/mail/mailboxAccessApi.d.ts +74 -0
  759. package/dist/lib/mail/mailboxAccessApi.js +56 -0
  760. package/dist/lib/mail/mailboxImportApi.d.ts +53 -0
  761. package/dist/lib/mail/mailboxImportApi.js +51 -0
  762. package/dist/lib/mail/messageBodySanitizer.d.ts +16 -0
  763. package/dist/lib/mail/messageBodySanitizer.js +118 -0
  764. package/dist/lib/mail/pushClient.d.ts +106 -0
  765. package/dist/lib/mail/pushClient.js +317 -0
  766. package/dist/lib/mail/sendEvents.d.ts +33 -0
  767. package/dist/lib/mail/sendEvents.js +44 -0
  768. package/dist/lib/mail/sendFailure.d.ts +16 -0
  769. package/dist/lib/mail/sendFailure.js +86 -0
  770. package/dist/lib/mail/senderListsApi.d.ts +69 -0
  771. package/dist/lib/mail/senderListsApi.js +126 -0
  772. package/dist/lib/search/queryGrammar.d.ts +51 -0
  773. package/dist/lib/search/queryGrammar.js +111 -0
  774. package/dist/lib/search/searchApi.d.ts +100 -0
  775. package/dist/lib/search/searchApi.js +107 -0
  776. package/dist/lib/search/searchScoring.d.ts +34 -0
  777. package/dist/lib/search/searchScoring.js +44 -0
  778. package/dist/lib/search/searchTier3.d.ts +64 -0
  779. package/dist/lib/search/searchTier3.js +335 -0
  780. package/dist/lib/tasks/tasksApi.d.ts +85 -0
  781. package/dist/lib/tasks/tasksApi.js +55 -0
  782. package/dist/lib/util/api.d.ts +160 -0
  783. package/dist/lib/util/api.js +251 -0
  784. package/dist/lib/util/apiClientContext.d.ts +7 -0
  785. package/dist/lib/util/apiClientContext.js +32 -0
  786. package/dist/lib/util/apiQuery.d.ts +32 -0
  787. package/dist/lib/util/apiQuery.js +42 -0
  788. package/dist/lib/util/clipboard.d.ts +7 -0
  789. package/dist/lib/util/clipboard.js +56 -0
  790. package/dist/lib/util/dateInput.d.ts +6 -0
  791. package/dist/lib/util/dateInput.js +14 -0
  792. package/dist/lib/util/timeZone.d.ts +12 -0
  793. package/dist/lib/util/timeZone.js +32 -0
  794. package/dist/lib/util/useCopyToClipboard.d.ts +12 -0
  795. package/dist/lib/util/useCopyToClipboard.js +34 -0
  796. package/dist/lib/util/useIsMobile.d.ts +10 -0
  797. package/dist/lib/util/useIsMobile.js +29 -0
  798. package/dist/lib/videoconf/videoMeetingsApi.d.ts +116 -0
  799. package/dist/lib/videoconf/videoMeetingsApi.js +49 -0
  800. package/lib/admin/auditLogApi.ts +48 -0
  801. package/lib/admin/distributionListsApi.ts +77 -0
  802. package/lib/admin/domainsApi.ts +113 -0
  803. package/lib/admin/escrowAccessRequestsApi.ts +110 -0
  804. package/lib/admin/escrowAuditLogApi.ts +101 -0
  805. package/lib/admin/escrowScopesApi.ts +112 -0
  806. package/lib/admin/leftoverMailboxApi.ts +120 -0
  807. package/lib/admin/mailboxPolicyApi.ts +38 -0
  808. package/lib/admin/matterExportApi.ts +62 -0
  809. package/lib/admin/matterSearchApi.ts +35 -0
  810. package/lib/admin/mattersApi.ts +86 -0
  811. package/lib/admin/pluginsApi.ts +339 -0
  812. package/lib/admin/retentionPolicyApi.ts +46 -0
  813. package/lib/admin/setupApi.ts +40 -0
  814. package/lib/admin/transportRulesApi.ts +106 -0
  815. package/lib/appearance/preferencesApi.ts +335 -0
  816. package/lib/auth/profileApi.ts +77 -0
  817. package/lib/auth/session.ts +238 -0
  818. package/lib/branding/brandingApi.ts +97 -0
  819. package/lib/branding/useBranding.ts +81 -0
  820. package/lib/calendar/calendarApi.ts +309 -0
  821. package/lib/calendar/calendarColors.ts +45 -0
  822. package/lib/calendar/calendarDragIds.ts +112 -0
  823. package/lib/calendar/calendarMutations.ts +236 -0
  824. package/lib/calendar/eventDescription.ts +211 -0
  825. package/lib/calendar/freeBusyApi.ts +197 -0
  826. package/lib/calendar/inviteApi.ts +154 -0
  827. package/lib/calendar/recurrence.ts +285 -0
  828. package/lib/components/avatar/ContactAvatar.tsx +47 -0
  829. package/lib/components/buttons/Button.tsx +40 -0
  830. package/lib/components/buttons/CopyButton.tsx +45 -0
  831. package/lib/components/feedback/Alert.tsx +13 -0
  832. package/lib/components/feedback/Skeleton.tsx +38 -0
  833. package/lib/components/forms/FormField.tsx +23 -0
  834. package/lib/components/navigation/BottomTabBar.tsx +66 -0
  835. package/lib/components/overlays/Drawer.tsx +72 -0
  836. package/lib/components/overlays/Modal.tsx +64 -0
  837. package/lib/components/overlays/PopoverPortal.tsx +74 -0
  838. package/lib/components/overlays/overlayStack.ts +165 -0
  839. package/lib/components/pickers/MiniDatePicker.tsx +90 -0
  840. package/lib/contacts/contactsApi.ts +289 -0
  841. package/lib/contacts/vcard.ts +197 -0
  842. package/lib/crypto/composeSecurity.ts +140 -0
  843. package/lib/crypto/encoding.ts +36 -0
  844. package/lib/crypto/escrowKeys.ts +74 -0
  845. package/lib/crypto/idleTimeout.ts +49 -0
  846. package/lib/crypto/keySession.ts +483 -0
  847. package/lib/crypto/keys.ts +105 -0
  848. package/lib/crypto/keyvaultApi.ts +674 -0
  849. package/lib/crypto/masterKey.ts +134 -0
  850. package/lib/crypto/masterKeyWraps.ts +269 -0
  851. package/lib/crypto/messageSecurity.ts +600 -0
  852. package/lib/crypto/mime.ts +568 -0
  853. package/lib/crypto/passkeyUnlock.ts +103 -0
  854. package/lib/crypto/passwordUnlock.ts +98 -0
  855. package/lib/crypto/recoveryCode.ts +93 -0
  856. package/lib/crypto/signingProviderApi.ts +135 -0
  857. package/lib/crypto/smime.ts +459 -0
  858. package/lib/crypto/smimeMessage.ts +491 -0
  859. package/lib/crypto/useIdleKeyTimeout.ts +176 -0
  860. package/lib/crypto/verificationSeal.ts +288 -0
  861. package/lib/mail/compose/composeQuoting.ts +243 -0
  862. package/lib/mail/compose/emojiData.ts +34 -0
  863. package/lib/mail/compose/giphyApi.ts +31 -0
  864. package/lib/mail/conversationsApi.ts +123 -0
  865. package/lib/mail/dataExportApi.ts +73 -0
  866. package/lib/mail/directoryApi.ts +161 -0
  867. package/lib/mail/erasureRequestApi.ts +71 -0
  868. package/lib/mail/flaggedMessages.ts +80 -0
  869. package/lib/mail/focusedInboxOverridesApi.ts +64 -0
  870. package/lib/mail/labelsApi.ts +71 -0
  871. package/lib/mail/mailAddress.ts +76 -0
  872. package/lib/mail/mailApi.ts +1286 -0
  873. package/lib/mail/mailDetailHooks.ts +57 -0
  874. package/lib/mail/mailFilterRulesApi.ts +116 -0
  875. package/lib/mail/mailSignaturesApi.ts +84 -0
  876. package/lib/mail/mailboxAccessApi.ts +106 -0
  877. package/lib/mail/mailboxImportApi.ts +87 -0
  878. package/lib/mail/messageBodySanitizer.ts +129 -0
  879. package/lib/mail/pushClient.ts +375 -0
  880. package/lib/mail/sendEvents.ts +72 -0
  881. package/lib/mail/sendFailure.ts +98 -0
  882. package/lib/mail/senderListsApi.ts +161 -0
  883. package/lib/search/queryGrammar.ts +179 -0
  884. package/lib/search/searchApi.ts +199 -0
  885. package/lib/search/searchScoring.ts +46 -0
  886. package/lib/search/searchTier3.ts +406 -0
  887. package/lib/tasks/tasksApi.ts +128 -0
  888. package/lib/util/api.ts +318 -0
  889. package/lib/util/apiClientContext.ts +35 -0
  890. package/lib/util/apiQuery.ts +61 -0
  891. package/lib/util/clipboard.ts +55 -0
  892. package/lib/util/dateInput.ts +15 -0
  893. package/lib/util/timeZone.ts +33 -0
  894. package/lib/util/useCopyToClipboard.ts +48 -0
  895. package/lib/util/useIsMobile.ts +34 -0
  896. package/lib/videoconf/videoMeetingsApi.ts +144 -0
  897. package/package.json +10 -4
@@ -0,0 +1,106 @@
1
+ ///////////////////////////////////////////////////////////////////////////////
2
+ // Copyright (C) 2026 Jean-Philippe Steinmetz
3
+ // SPDX-License-Identifier: MPL-2.0
4
+ ///////////////////////////////////////////////////////////////////////////////
5
+ /** Typed wrappers over `@rapidmx/restapi`'s `/mail/calendar-events` REST surface — see `mailApi.ts`'s own
6
+ * header comment for the shared ACL/authorization model every wrapper file here follows. Recurrence
7
+ * expansion happens entirely client-side (see `apps/shared/lib/recurrence.ts`) — the backend stores/returns
8
+ * `RecurrenceRule` as-is and does no RFC5545 expansion of its own. */
9
+ import { withClient } from "../util/api.js";
10
+ import { buildQuery } from "../util/apiQuery.js";
11
+ /** The guest permissions an event has when none were chosen (Google Calendar's own defaults). */
12
+ export const DEFAULT_GUEST_PERMISSIONS = { guestsCanModify: false, guestsCanInviteOthers: true, guestsCanSeeGuestList: true };
13
+ /** The guest permissions `source` says, a missing (or `null`) flag reading as its default - an event stored before they existed carries none. */
14
+ export function guestPermissionsOf(source) {
15
+ return {
16
+ guestsCanModify: source.guestsCanModify ?? DEFAULT_GUEST_PERMISSIONS.guestsCanModify,
17
+ guestsCanInviteOthers: source.guestsCanInviteOthers ?? DEFAULT_GUEST_PERMISSIONS.guestsCanInviteOthers,
18
+ guestsCanSeeGuestList: source.guestsCanSeeGuestList ?? DEFAULT_GUEST_PERMISSIONS.guestsCanSeeGuestList,
19
+ };
20
+ }
21
+ /** The visibility an event has, `"default"` when it says none. */
22
+ export function visibilityOf(event) {
23
+ return event.visibility ?? "default";
24
+ }
25
+ const LIST_PAGE_SIZE = 500;
26
+ const LIST_CALENDAR_EVENTS_MAX_PAGES = 100;
27
+ /**
28
+ * Lists every event in a folder (same "fetch the flat list, filter client-side" contract as
29
+ * `contactsApi.ts`'s `listContacts`/`tasksApi.ts`'s `listTasks`), for the caller to expand and filter
30
+ * to a visible range itself (see `recurrence.ts`'s `expandAllOccurrences`). This deliberately does
31
+ * *not* push `startDate`/`endDate` range filtering down to the server via `@rapidmx/restapi`'s
32
+ * `field=lte(v)`/`gte(v)` query-operator DSL — confirmed directly against a running instance that
33
+ * `CalendarEventMongo`'s `startDate`/`endDate` are persisted as plain strings despite being typed
34
+ * `Date`, so a Mongo `$lte`/`$gte` comparison against them (a real `Date` operand) matches nothing at
35
+ * all, silently returning zero events for *any* date-bounded query. Client-side filtering sidesteps
36
+ * that entirely and needs no fix to land here.
37
+ *
38
+ * Pages through the whole folder (`limit=500`, the server's own page-size cap) until a short page comes
39
+ * back, so a calendar with more than one page of events isn't silently truncated. A hard cap of
40
+ * `LIST_CALENDAR_EVENTS_MAX_PAGES` pages guards against looping forever should a server ever ignore
41
+ * `page` and keep returning full pages.
42
+ */
43
+ export async function listCalendarEvents(folderUid, client) {
44
+ const events = [];
45
+ for (let page = 0; page < LIST_CALENDAR_EVENTS_MAX_PAGES; page++) {
46
+ const batch = await withClient(client, `/mail/calendar-events?${buildQuery({ limit: LIST_PAGE_SIZE, page }, { folderUid })}`);
47
+ events.push(...batch);
48
+ if (batch.length < LIST_PAGE_SIZE) {
49
+ break;
50
+ }
51
+ }
52
+ return events;
53
+ }
54
+ export function getCalendarEvent(uid, client) {
55
+ return withClient(client, `/mail/calendar-events/${encodeURIComponent(uid)}`);
56
+ }
57
+ export function createCalendarEvent(input, client) {
58
+ return withClient(client, "/mail/calendar-events", {
59
+ method: "POST",
60
+ body: JSON.stringify({
61
+ allDay: false,
62
+ attendees: [],
63
+ status: "confirmed",
64
+ busyStatus: "busy",
65
+ icalUid: crypto.randomUUID(),
66
+ sequence: 0,
67
+ ...input,
68
+ }),
69
+ });
70
+ }
71
+ export function updateCalendarEvent(input, client) {
72
+ return withClient(client, `/mail/calendar-events/${encodeURIComponent(input.uid)}`, {
73
+ method: "PUT",
74
+ body: JSON.stringify(input),
75
+ });
76
+ }
77
+ export function deleteCalendarEvent(uid, version, client) {
78
+ return withClient(client, `/mail/calendar-events/${encodeURIComponent(uid)}?version=${version}`, { method: "DELETE" });
79
+ }
80
+ /**
81
+ * Responds to a meeting invite as the calling mailbox's own attendee entry. Synchronous — unlike
82
+ * `recallMessage()` in `mailApi.ts`, this immediately mutates and persists the response (the iTIP
83
+ * REPLY email send is best-effort server-side and never affects this call's outcome). On
84
+ * `"accepted"`/`"tentative"` the whole updated `CalendarEvent` comes back, with only the calling
85
+ * attendee's own `responseStatus` changed. On `"declined"`, the backend instead soft-deletes the
86
+ * mailbox's own copy of the event and returns only `{ uid }` — the caller should treat a decline the
87
+ * same as a delete rather than expecting an updated event back.
88
+ */
89
+ export function respondToEvent(uid, responseStatus, client) {
90
+ return withClient(client, `/mail/calendar-events/${encodeURIComponent(uid)}/respond`, {
91
+ method: "POST",
92
+ body: JSON.stringify({ responseStatus }),
93
+ });
94
+ }
95
+ /**
96
+ * Asks the organizer to change an event, as a guest (not the organizer) whose copy allows it: the title, location, description or time need
97
+ * `guestsCanModify`, added guests need `guestsCanInviteOthers` (403 otherwise; 400 when nothing differs from what the event has, or a value is invalid).
98
+ * Nothing changes on this mailbox's own copy - the request is mailed to the organizer, and when the change is allowed it is applied there and
99
+ * arrives back later as an ordinary update of the invitation.
100
+ */
101
+ export function requestEventChange(uid, request, client) {
102
+ return withClient(client, `/mail/calendar-events/${encodeURIComponent(uid)}/request-change`, {
103
+ method: "POST",
104
+ body: JSON.stringify(request),
105
+ });
106
+ }
@@ -0,0 +1,18 @@
1
+ /** A fixed client-side color palette for calendars, matching the plan's "no new `Category`-style
2
+ * backend entity" approach already used for Contacts' categories: `Folder.color` just stores one of
3
+ * these hex values (or, in principle, any string — an unrecognized one still works fine as a raw CSS
4
+ * color), the palette itself never needs to round-trip through the backend. */
5
+ import { Folder } from "../mail/mailApi.js";
6
+ export declare const CALENDAR_COLOR_PALETTE: string[];
7
+ /** The color a mailbox's original auto-provisioned calendar effectively had before this field
8
+ * existed — kept as the fallback so every pre-existing calendar keeps looking the same. */
9
+ export declare const DEFAULT_CALENDAR_COLOR: string;
10
+ /** `fallback` replaces `DEFAULT_CALENDAR_COLOR` for a folder with no color of its own - e.g. a shared
11
+ * mailbox's calendar falling back to that mailbox's `accentColorForMailbox()`, so it doesn't render in
12
+ * the same default blue as the caller's own calendar. An explicit `Folder.color` always wins. */
13
+ export declare function colorForFolder(folder: Pick<Folder, "color">, fallback?: string): string;
14
+ /** A stable per-mailbox color for grouping one mailbox's calendars together (sidebar section accent, and
15
+ * the fallback color for its uncolored calendars). Deterministic hash of `mailboxUid` into the palette
16
+ * minus `DEFAULT_CALENDAR_COLOR`, so another mailbox never collides with the default a caller's own
17
+ * calendar already uses. Client-side only - nothing is persisted. */
18
+ export declare function accentColorForMailbox(mailboxUid: string): string;
@@ -0,0 +1,39 @@
1
+ ///////////////////////////////////////////////////////////////////////////////
2
+ // Copyright (C) 2026 Jean-Philippe Steinmetz
3
+ // SPDX-License-Identifier: MPL-2.0
4
+ ///////////////////////////////////////////////////////////////////////////////
5
+ /** A fixed client-side color palette for calendars, matching the plan's "no new `Category`-style
6
+ * backend entity" approach already used for Contacts' categories: `Folder.color` just stores one of
7
+ * these hex values (or, in principle, any string — an unrecognized one still works fine as a raw CSS
8
+ * color), the palette itself never needs to round-trip through the backend. */
9
+ export const CALENDAR_COLOR_PALETTE = [
10
+ "#2563eb", // blue
11
+ "#7c3aed", // violet
12
+ "#db2777", // pink
13
+ "#dc2626", // red
14
+ "#ea580c", // orange
15
+ "#ca8a04", // amber
16
+ "#16a34a", // green
17
+ "#0d9488", // teal
18
+ ];
19
+ /** The color a mailbox's original auto-provisioned calendar effectively had before this field
20
+ * existed — kept as the fallback so every pre-existing calendar keeps looking the same. */
21
+ export const DEFAULT_CALENDAR_COLOR = CALENDAR_COLOR_PALETTE[0];
22
+ /** `fallback` replaces `DEFAULT_CALENDAR_COLOR` for a folder with no color of its own - e.g. a shared
23
+ * mailbox's calendar falling back to that mailbox's `accentColorForMailbox()`, so it doesn't render in
24
+ * the same default blue as the caller's own calendar. An explicit `Folder.color` always wins. */
25
+ export function colorForFolder(folder, fallback = DEFAULT_CALENDAR_COLOR) {
26
+ return folder.color || fallback;
27
+ }
28
+ /** A stable per-mailbox color for grouping one mailbox's calendars together (sidebar section accent, and
29
+ * the fallback color for its uncolored calendars). Deterministic hash of `mailboxUid` into the palette
30
+ * minus `DEFAULT_CALENDAR_COLOR`, so another mailbox never collides with the default a caller's own
31
+ * calendar already uses. Client-side only - nothing is persisted. */
32
+ export function accentColorForMailbox(mailboxUid) {
33
+ const choices = CALENDAR_COLOR_PALETTE.slice(1);
34
+ let hash = 0;
35
+ for (let i = 0; i < mailboxUid.length; i++) {
36
+ hash = (hash * 31 + mailboxUid.charCodeAt(i)) >>> 0;
37
+ }
38
+ return choices[hash % choices.length];
39
+ }
@@ -0,0 +1,42 @@
1
+ /**
2
+ * `@dnd-kit/core` identifies draggables/droppables purely by string id — this module owns the
3
+ * encoding scheme for calendar drag ids and, more importantly, `resolveDragAction()`: a pure
4
+ * function turning a drag-end's (active id, over id) pair into "move this occurrence by N ms" or
5
+ * "resize this occurrence's end to this instant", *without* touching `@dnd-kit` itself. Kept pure and
6
+ * dependency-free from the grid components on purpose: `@dnd-kit`'s pointer-based drag sensors are
7
+ * awkward to drive from jsdom in tests (they need real `PointerEvent`/`getBoundingClientRect`
8
+ * behavior a headless DOM doesn't fully provide), but the *decision* a drag-end makes is ordinary
9
+ * data-in-data-out logic that's trivial to unit test directly — see `calendarDragIds.test.ts`. The
10
+ * grid views (`MonthView`/`TimeGridView`) only need to tag their draggable/droppable elements with
11
+ * these ids correctly; the calendar page's `onDragEnd` calls `resolveDragAction` and then one of
12
+ * `calendarMutations.ts`'s `moveOccurrence`/`resizeOccurrenceEnd`.
13
+ */
14
+ import { CalendarOccurrence } from "./recurrence.js";
15
+ /**
16
+ * A month-view day cell's droppable id, for the given day (any time-of-day on that calendar date) —
17
+ * encoded as the runtime's *local* `yyyy-MM-dd`, matching the local-midnight day dates the grid views
18
+ * build via `date-fns`.
19
+ */
20
+ export declare function dayDropId(date: Date): string;
21
+ /** A week/day-view time slot's droppable id, rounded to the given date-time instant. */
22
+ export declare function slotDropId(date: Date): string;
23
+ /** An event chip/block's draggable id (drag-to-move). */
24
+ export declare function eventDragId(occurrence: CalendarOccurrence): string;
25
+ /** An event block's resize-handle draggable id (drag-to-resize, week/day view only). */
26
+ export declare function resizeDragId(occurrence: CalendarOccurrence): string;
27
+ export type DragAction = {
28
+ type: "move";
29
+ occurrence: CalendarOccurrence;
30
+ deltaMs: number;
31
+ } | {
32
+ type: "resize";
33
+ occurrence: CalendarOccurrence;
34
+ newEnd: Date;
35
+ };
36
+ /**
37
+ * Resolves a `@dnd-kit` drag-end's `active`/`over` ids into the action it represents, or `null` if
38
+ * the drop doesn't correspond to anything actionable (dropped outside any droppable, or the dragged
39
+ * id doesn't match any occurrence currently on the grid — e.g. it was removed by an in-flight reload
40
+ * mid-drag).
41
+ */
42
+ export declare function resolveDragAction(activeId: string, overId: string | undefined, occurrences: CalendarOccurrence[]): DragAction | null;
@@ -0,0 +1,92 @@
1
+ ///////////////////////////////////////////////////////////////////////////////
2
+ // Copyright (C) 2026 Jean-Philippe Steinmetz
3
+ // SPDX-License-Identifier: MPL-2.0
4
+ ///////////////////////////////////////////////////////////////////////////////
5
+ /**
6
+ * `@dnd-kit/core` identifies draggables/droppables purely by string id — this module owns the
7
+ * encoding scheme for calendar drag ids and, more importantly, `resolveDragAction()`: a pure
8
+ * function turning a drag-end's (active id, over id) pair into "move this occurrence by N ms" or
9
+ * "resize this occurrence's end to this instant", *without* touching `@dnd-kit` itself. Kept pure and
10
+ * dependency-free from the grid components on purpose: `@dnd-kit`'s pointer-based drag sensors are
11
+ * awkward to drive from jsdom in tests (they need real `PointerEvent`/`getBoundingClientRect`
12
+ * behavior a headless DOM doesn't fully provide), but the *decision* a drag-end makes is ordinary
13
+ * data-in-data-out logic that's trivial to unit test directly — see `calendarDragIds.test.ts`. The
14
+ * grid views (`MonthView`/`TimeGridView`) only need to tag their draggable/droppable elements with
15
+ * these ids correctly; the calendar page's `onDragEnd` calls `resolveDragAction` and then one of
16
+ * `calendarMutations.ts`'s `moveOccurrence`/`resizeOccurrenceEnd`.
17
+ */
18
+ const DAY_ID_PREFIX = "day:";
19
+ const SLOT_ID_PREFIX = "slot:";
20
+ const RESIZE_ID_PREFIX = "resize:";
21
+ /**
22
+ * A month-view day cell's droppable id, for the given day (any time-of-day on that calendar date) —
23
+ * encoded as the runtime's *local* `yyyy-MM-dd`, matching the local-midnight day dates the grid views
24
+ * build via `date-fns`.
25
+ */
26
+ export function dayDropId(date) {
27
+ const yyyy = String(date.getFullYear()).padStart(4, "0");
28
+ const mm = String(date.getMonth() + 1).padStart(2, "0");
29
+ const dd = String(date.getDate()).padStart(2, "0");
30
+ return `${DAY_ID_PREFIX}${yyyy}-${mm}-${dd}`;
31
+ }
32
+ /** A week/day-view time slot's droppable id, rounded to the given date-time instant. */
33
+ export function slotDropId(date) {
34
+ return `${SLOT_ID_PREFIX}${date.toISOString()}`;
35
+ }
36
+ /** An event chip/block's draggable id (drag-to-move). */
37
+ export function eventDragId(occurrence) {
38
+ return occurrence.occurrenceKey;
39
+ }
40
+ /** An event block's resize-handle draggable id (drag-to-resize, week/day view only). */
41
+ export function resizeDragId(occurrence) {
42
+ return `${RESIZE_ID_PREFIX}${occurrence.occurrenceKey}`;
43
+ }
44
+ /**
45
+ * Resolves a `@dnd-kit` drag-end's `active`/`over` ids into the action it represents, or `null` if
46
+ * the drop doesn't correspond to anything actionable (dropped outside any droppable, or the dragged
47
+ * id doesn't match any occurrence currently on the grid — e.g. it was removed by an in-flight reload
48
+ * mid-drag).
49
+ */
50
+ export function resolveDragAction(activeId, overId, occurrences) {
51
+ if (!overId) {
52
+ return null;
53
+ }
54
+ const isResize = activeId.startsWith(RESIZE_ID_PREFIX);
55
+ const occurrenceKey = isResize ? activeId.slice(RESIZE_ID_PREFIX.length) : activeId;
56
+ const occurrence = occurrences.find((o) => o.occurrenceKey === occurrenceKey);
57
+ if (!occurrence) {
58
+ return null;
59
+ }
60
+ if (isResize) {
61
+ if (!overId.startsWith(SLOT_ID_PREFIX)) {
62
+ return null;
63
+ }
64
+ return { type: "resize", occurrence, newEnd: new Date(overId.slice(SLOT_ID_PREFIX.length)) };
65
+ }
66
+ if (overId.startsWith(DAY_ID_PREFIX)) {
67
+ // Moving a timed event to another day keeps the occurrence's local wall-clock start time, so the delta is
68
+ // "same local time on the target day" minus the original start — a whole number of calendar
69
+ // days, which is not always a multiple of 24h when the move crosses a DST change.
70
+ const [year, month, day] = overId.slice(DAY_ID_PREFIX.length).split("-").map(Number);
71
+ // An all-day event's start is a UTC-midnight date-only value, so its target is that calendar date's
72
+ // UTC midnight - never "the same local time", which west of UTC reads the stored midnight as the
73
+ // previous evening and lands the event a day late.
74
+ const source = new Date(occurrence.startDate);
75
+ const target = new Date(source.getTime());
76
+ if (occurrence.allDay) {
77
+ target.setTime(Date.UTC(year, month - 1, day));
78
+ }
79
+ else {
80
+ target.setFullYear(year, month - 1, day);
81
+ }
82
+ if (Number.isNaN(target.getTime())) {
83
+ return null;
84
+ }
85
+ return { type: "move", occurrence, deltaMs: target.getTime() - source.getTime() };
86
+ }
87
+ if (overId.startsWith(SLOT_ID_PREFIX)) {
88
+ const targetSlot = new Date(overId.slice(SLOT_ID_PREFIX.length));
89
+ return { type: "move", occurrence, deltaMs: targetSlot.getTime() - new Date(occurrence.startDate).getTime() };
90
+ }
91
+ return null;
92
+ }
@@ -0,0 +1,68 @@
1
+ /**
2
+ * Higher-level calendar mutations shared by the event modal (edit/delete) and the grid views'
3
+ * drag-and-drop handlers (move/resize) — both need the exact same "this occurrence vs. the entire
4
+ * series" logic for a recurring event, so it lives here once rather than being duplicated.
5
+ *
6
+ * A recurring event has no per-occurrence record server-side — `@rapidmx/restapi` stores only the
7
+ * master `CalendarEvent` plus its `RecurrenceRule` (see `recurrence.ts`'s header comment). Changing
8
+ * (or deleting) a single occurrence is therefore always a two-part operation: add that occurrence's
9
+ * original start to the master's `recurrenceRule.exceptions` (so it stops being generated), and, for
10
+ * an edit (not a delete), separately create a new standalone `CalendarEvent` carrying the edited
11
+ * fields, with `recurrenceId` set to that original occurrence's start for traceability — mirroring
12
+ * how `CalendarEvent.recurrenceId` is documented to work.
13
+ */
14
+ import { CalendarEvent, CalendarEventInput } from "./calendarApi.js";
15
+ import { CalendarOccurrence } from "./recurrence.js";
16
+ import { ApiClient } from "../util/api.js";
17
+ /** `saveEventSeries()`'s result: the saved master, plus whether its detached occurrences could be kept in
18
+ * step with a rescheduled series. */
19
+ export type SeriesSaveResult = CalendarEvent & {
20
+ /** `true` when the series' start moved but at least one detached occurrence (a separate event sharing
21
+ * the master's `icalUid`, with a `recurrenceId`) couldn't be re-pointed at its occurrence's new start -
22
+ * that occurrence may then show up twice (the detached copy plus a regenerated one). The master itself
23
+ * was saved. Absent when nothing needed re-pointing or every update succeeded. */
24
+ detachedOccurrenceSyncFailed?: boolean;
25
+ };
26
+ /**
27
+ * Applies edited `fields` to every occurrence of a recurring event's series (the master record).
28
+ *
29
+ * `fields.startDate` must be the *master's* new start (web-client's `toSeriesFields()` computes it). When
30
+ * it moves the series (or changes its `timezone`/`allDay`), every occurrence moves by the same wall-clock
31
+ * delta, so everything that identifies an occurrence by its original start moves with it: the rule's
32
+ * `exceptions` (else a deleted occurrence reappears and a different one vanishes) and the `recurrenceId` of
33
+ * each detached occurrence in the master's folder (else the server-side reminder/iTIP logic, which matches
34
+ * overrides by `recurrenceId`, no longer pairs them). Detached occurrences keep their own edited times. The
35
+ * master is saved first; re-pointing detached occurrences is best-effort, reported through
36
+ * `detachedOccurrenceSyncFailed` rather than thrown. Series edits that don't move the start make one PUT.
37
+ */
38
+ export declare function saveEventSeries(occurrence: CalendarOccurrence, fields: Partial<CalendarEventInput>, client?: ApiClient): Promise<SeriesSaveResult>;
39
+ /**
40
+ * Applies edited `fields` to just this one occurrence of a recurring event, detaching it into its own
41
+ * standalone (non-recurring) event and excluding the original occurrence from the series.
42
+ *
43
+ * The detached event is created *first*, and only then is the original occurrence excluded from the
44
+ * master — so a failure part-way never makes the occurrence silently disappear. If adding the
45
+ * exception fails, the just-created detached event is deleted again (best-effort) and the original
46
+ * error is rethrown. The detached event keeps the master's `icalUid` and records the occurrence's
47
+ * original start as its `recurrenceId` (the RFC5545 way of identifying a modified instance), and never
48
+ * carries the series' `recurrenceRule` — even if `fields` includes one (e.g. the event modal's full
49
+ * field set).
50
+ */
51
+ export declare function detachOccurrence(occurrence: CalendarOccurrence, fields: Partial<CalendarEventInput>, client?: ApiClient): Promise<CalendarEvent>;
52
+ /** Deletes an entire recurring series (or a genuinely non-recurring event) outright. */
53
+ export declare function deleteEventSeries(occurrence: CalendarOccurrence, client?: ApiClient): Promise<void>;
54
+ /** Removes just this one occurrence from a recurring series, leaving the rest of the series intact. */
55
+ export declare function deleteEventOccurrence(occurrence: CalendarOccurrence, client?: ApiClient): Promise<CalendarEvent>;
56
+ /**
57
+ * Moves `occurrence` by `deltaMs` (drag-to-move on a grid), preserving its original duration. A
58
+ * recurring occurrence is always detached into its own standalone event — matching Outlook's own
59
+ * drag behavior, which never silently reschedules an entire series from a single dragged instance;
60
+ * moving the whole series is only ever done explicitly, via the event modal's "entire series" option.
61
+ */
62
+ export declare function moveOccurrence(occurrence: CalendarOccurrence, deltaMs: number, client?: ApiClient): Promise<CalendarEvent>;
63
+ /**
64
+ * Resizes `occurrence`'s end time (drag-to-resize on a week/day grid), keeping its start fixed and
65
+ * clamping to a 15-minute minimum duration so a resize can never invert start/end. Same
66
+ * always-detaches-a-recurring-occurrence reasoning as `moveOccurrence` above.
67
+ */
68
+ export declare function resizeOccurrenceEnd(occurrence: CalendarOccurrence, newEndDate: Date, client?: ApiClient): Promise<CalendarEvent>;
@@ -0,0 +1,190 @@
1
+ ///////////////////////////////////////////////////////////////////////////////
2
+ // Copyright (C) 2026 Jean-Philippe Steinmetz
3
+ // SPDX-License-Identifier: MPL-2.0
4
+ ///////////////////////////////////////////////////////////////////////////////
5
+ /**
6
+ * Higher-level calendar mutations shared by the event modal (edit/delete) and the grid views'
7
+ * drag-and-drop handlers (move/resize) — both need the exact same "this occurrence vs. the entire
8
+ * series" logic for a recurring event, so it lives here once rather than being duplicated.
9
+ *
10
+ * A recurring event has no per-occurrence record server-side — `@rapidmx/restapi` stores only the
11
+ * master `CalendarEvent` plus its `RecurrenceRule` (see `recurrence.ts`'s header comment). Changing
12
+ * (or deleting) a single occurrence is therefore always a two-part operation: add that occurrence's
13
+ * original start to the master's `recurrenceRule.exceptions` (so it stops being generated), and, for
14
+ * an edit (not a delete), separately create a new standalone `CalendarEvent` carrying the edited
15
+ * fields, with `recurrenceId` set to that original occurrence's start for traceability — mirroring
16
+ * how `CalendarEvent.recurrenceId` is documented to work.
17
+ */
18
+ import { createCalendarEvent, deleteCalendarEvent, getCalendarEvent, listCalendarEvents, updateCalendarEvent, } from "./calendarApi.js";
19
+ import { fromEventWallClock, toEventWallClock } from "./recurrence.js";
20
+ /** `client`, given by every function below, is an explicit `ApiClient` from `createApiClient()` (e.g. one
21
+ * account of a multi-account app) to call instead of the default global `apiFetch()` - see `withClient()`'s
22
+ * own doc comment in `util/api.ts`. Omitted (the default), every function here behaves exactly as before,
23
+ * and threads the same `client` through to every `calendarApi.ts` call it makes internally. */
24
+ const MS_PER_DAY = 24 * 60 * 60 * 1000;
25
+ function positiveModulo(value, modulus) {
26
+ return ((value % modulus) + modulus) % modulus;
27
+ }
28
+ function addException(event, occurrenceStart, client) {
29
+ const rule = event.recurrenceRule;
30
+ return updateCalendarEvent({
31
+ uid: event.uid,
32
+ version: event.version,
33
+ recurrenceRule: { ...rule, exceptions: [...rule.exceptions, occurrenceStart] },
34
+ }, client);
35
+ }
36
+ /**
37
+ * Applies edited `fields` to every occurrence of a recurring event's series (the master record).
38
+ *
39
+ * `fields.startDate` must be the *master's* new start (web-client's `toSeriesFields()` computes it). When
40
+ * it moves the series (or changes its `timezone`/`allDay`), every occurrence moves by the same wall-clock
41
+ * delta, so everything that identifies an occurrence by its original start moves with it: the rule's
42
+ * `exceptions` (else a deleted occurrence reappears and a different one vanishes) and the `recurrenceId` of
43
+ * each detached occurrence in the master's folder (else the server-side reminder/iTIP logic, which matches
44
+ * overrides by `recurrenceId`, no longer pairs them). Detached occurrences keep their own edited times. The
45
+ * master is saved first; re-pointing detached occurrences is best-effort, reported through
46
+ * `detachedOccurrenceSyncFailed` rather than thrown. Series edits that don't move the start make one PUT.
47
+ */
48
+ export async function saveEventSeries(occurrence, fields, client) {
49
+ const update = { uid: occurrence.uid, version: occurrence.version, ...fields };
50
+ // A shift can be needed even without an explicit startDate: changing timezone or allDay reinterprets the
51
+ // master's existing (unchanged) instant onto a different wall clock, exactly as the doc comment above
52
+ // promises - so all three fields, not just startDate, gate entry into the shift path below.
53
+ if (fields.startDate === undefined && fields.timezone === undefined && fields.allDay === undefined) {
54
+ return updateCalendarEvent(update, client);
55
+ }
56
+ const master = await getCalendarEvent(occurrence.uid, client);
57
+ const newTimezone = fields.timezone ?? master.timezone;
58
+ const newAllDay = fields.allDay ?? master.allDay;
59
+ const oldStartWall = toEventWallClock(Date.parse(master.startDate), master.timezone, master.allDay);
60
+ const newStartInstant = Date.parse(fields.startDate ?? master.startDate);
61
+ const deltaWallMs = toEventWallClock(newStartInstant, newTimezone, newAllDay) - oldStartWall;
62
+ if (deltaWallMs === 0 && newTimezone === master.timezone && newAllDay === master.allDay) {
63
+ return updateCalendarEvent(update, client);
64
+ }
65
+ // An occurrence is identified by its nominal wall-clock start (the rule's date + the master's time of day),
66
+ // not by the instant's own wall time: one that fell in a DST gap was pushed forward (02:30 -> 03:30 EDT),
67
+ // so shifting that pushed wall time would miss the occurrence the moved rule generates on that date.
68
+ const masterTimeOfDay = positiveModulo(oldStartWall, MS_PER_DAY);
69
+ const nominalWall = (instantMs) => {
70
+ const wall = toEventWallClock(instantMs, master.timezone, master.allDay);
71
+ const dayStart = wall - positiveModulo(wall, MS_PER_DAY);
72
+ const candidates = [dayStart + masterTimeOfDay, dayStart - MS_PER_DAY + masterTimeOfDay];
73
+ // An instant the rule couldn't have generated (e.g. a hand-edited exception) shifts by its own wall time.
74
+ return candidates.find((candidate) => fromEventWallClock(candidate, master.timezone, master.allDay) === instantMs) ?? wall;
75
+ };
76
+ const shift = (instant) => new Date(fromEventWallClock(nominalWall(Date.parse(instant)) + deltaWallMs, newTimezone, newAllDay)).toISOString();
77
+ const rule = fields.recurrenceRule ?? master.recurrenceRule;
78
+ if (rule) {
79
+ update.recurrenceRule = { ...rule, exceptions: rule.exceptions.map(shift) };
80
+ }
81
+ const saved = await updateCalendarEvent(update, client);
82
+ let detachedOccurrenceSyncFailed = false;
83
+ try {
84
+ const detached = (await listCalendarEvents(master.folderUid, client)).filter((event) => event.icalUid === master.icalUid && event.uid !== master.uid && event.recurrenceId);
85
+ for (const event of detached) {
86
+ try {
87
+ // `recurrenceId` isn't part of `CalendarEventInput`, but restapi's update accepts it (the same
88
+ // way `detachOccurrence()` sends it on create).
89
+ await updateCalendarEvent({ uid: event.uid, version: event.version, recurrenceId: shift(event.recurrenceId) }, client);
90
+ }
91
+ catch {
92
+ detachedOccurrenceSyncFailed = true;
93
+ }
94
+ }
95
+ }
96
+ catch {
97
+ detachedOccurrenceSyncFailed = true;
98
+ }
99
+ return detachedOccurrenceSyncFailed ? { ...saved, detachedOccurrenceSyncFailed } : saved;
100
+ }
101
+ /**
102
+ * Applies edited `fields` to just this one occurrence of a recurring event, detaching it into its own
103
+ * standalone (non-recurring) event and excluding the original occurrence from the series.
104
+ *
105
+ * The detached event is created *first*, and only then is the original occurrence excluded from the
106
+ * master — so a failure part-way never makes the occurrence silently disappear. If adding the
107
+ * exception fails, the just-created detached event is deleted again (best-effort) and the original
108
+ * error is rethrown. The detached event keeps the master's `icalUid` and records the occurrence's
109
+ * original start as its `recurrenceId` (the RFC5545 way of identifying a modified instance), and never
110
+ * carries the series' `recurrenceRule` — even if `fields` includes one (e.g. the event modal's full
111
+ * field set).
112
+ */
113
+ export async function detachOccurrence(occurrence, fields, client) {
114
+ const originalStart = occurrence.recurrenceId;
115
+ // `icalUid`/`recurrenceId` aren't part of `CalendarEventInput`, but `@rapidmx/restapi`'s
116
+ // `CalendarEvent` model accepts both on create (and `createCalendarEvent` already sends `icalUid`).
117
+ const input = {
118
+ mailboxUid: occurrence.mailboxUid,
119
+ folderUid: occurrence.folderUid,
120
+ title: occurrence.title,
121
+ location: occurrence.location,
122
+ startDate: occurrence.startDate,
123
+ endDate: occurrence.endDate,
124
+ allDay: occurrence.allDay,
125
+ timezone: occurrence.timezone,
126
+ organizer: occurrence.organizer,
127
+ attendees: occurrence.attendees,
128
+ status: occurrence.status,
129
+ busyStatus: occurrence.busyStatus,
130
+ reminderMinutesBeforeStart: occurrence.reminderMinutesBeforeStart,
131
+ autoReplyEnabled: occurrence.autoReplyEnabled,
132
+ autoReplyMessage: occurrence.autoReplyMessage,
133
+ // A detached occurrence keeps what the series says about its description, visibility and guests (an absent value is the default).
134
+ description: occurrence.description ?? undefined,
135
+ descriptionHtml: occurrence.descriptionHtml ?? undefined,
136
+ visibility: occurrence.visibility ?? undefined,
137
+ guestsCanModify: occurrence.guestsCanModify ?? undefined,
138
+ guestsCanInviteOthers: occurrence.guestsCanInviteOthers ?? undefined,
139
+ guestsCanSeeGuestList: occurrence.guestsCanSeeGuestList ?? undefined,
140
+ ...fields,
141
+ recurrenceRule: undefined,
142
+ icalUid: occurrence.icalUid,
143
+ recurrenceId: originalStart,
144
+ };
145
+ const created = await createCalendarEvent(input, client);
146
+ try {
147
+ await addException(occurrence, originalStart, client);
148
+ }
149
+ catch (err) {
150
+ await deleteCalendarEvent(created.uid, created.version, client).catch(() => undefined);
151
+ throw err;
152
+ }
153
+ return created;
154
+ }
155
+ /** Deletes an entire recurring series (or a genuinely non-recurring event) outright. */
156
+ export function deleteEventSeries(occurrence, client) {
157
+ return deleteCalendarEvent(occurrence.uid, occurrence.version, client);
158
+ }
159
+ /** Removes just this one occurrence from a recurring series, leaving the rest of the series intact. */
160
+ export function deleteEventOccurrence(occurrence, client) {
161
+ return addException(occurrence, occurrence.recurrenceId, client);
162
+ }
163
+ /**
164
+ * Moves `occurrence` by `deltaMs` (drag-to-move on a grid), preserving its original duration. A
165
+ * recurring occurrence is always detached into its own standalone event — matching Outlook's own
166
+ * drag behavior, which never silently reschedules an entire series from a single dragged instance;
167
+ * moving the whole series is only ever done explicitly, via the event modal's "entire series" option.
168
+ */
169
+ export function moveOccurrence(occurrence, deltaMs, client) {
170
+ const fields = {
171
+ startDate: new Date(new Date(occurrence.startDate).getTime() + deltaMs).toISOString(),
172
+ endDate: new Date(new Date(occurrence.endDate).getTime() + deltaMs).toISOString(),
173
+ };
174
+ return occurrence.isRecurringOccurrence
175
+ ? detachOccurrence(occurrence, fields, client)
176
+ : updateCalendarEvent({ uid: occurrence.uid, version: occurrence.version, ...fields }, client);
177
+ }
178
+ /**
179
+ * Resizes `occurrence`'s end time (drag-to-resize on a week/day grid), keeping its start fixed and
180
+ * clamping to a 15-minute minimum duration so a resize can never invert start/end. Same
181
+ * always-detaches-a-recurring-occurrence reasoning as `moveOccurrence` above.
182
+ */
183
+ export function resizeOccurrenceEnd(occurrence, newEndDate, client) {
184
+ const start = new Date(occurrence.startDate);
185
+ const minEnd = new Date(start.getTime() + 15 * 60000);
186
+ const endDate = (newEndDate.getTime() > minEnd.getTime() ? newEndDate : minEnd).toISOString();
187
+ return occurrence.isRecurringOccurrence
188
+ ? detachOccurrence(occurrence, { endDate }, client)
189
+ : updateCalendarEvent({ uid: occurrence.uid, version: occurrence.version, endDate }, client);
190
+ }
@@ -0,0 +1,43 @@
1
+ /**
2
+ * An event's description as a client handles it. `@rapidmx/restapi` stores the rich text as HTML it has sanitized to a handful of tags
3
+ * (`b`/`strong`, `i`/`em`, `u`, `br`, `p`, `ul`/`ol`/`li`, and `a` with an `http`, `https` or `mailto` `href`), and a client must still never trust it: a
4
+ * description can also arrive in an invitation from anyone. So the HTML is never put in the page as it is. `parseEventDescription()` reads it into a small
5
+ * tree of only those elements - built from what the browser's own parser found, by copying text and one attribute across, so nothing else can survive - and
6
+ * everything a client shows or sends is made from that tree: `renderable` by React elements (no `dangerouslySetInnerHTML`), written back out as canonical
7
+ * HTML (`sanitizeEventDescriptionHtml()`) or as plain text (`htmlToPlainText()`, the same text the server derives).
8
+ *
9
+ * Reading needs a DOM (`DOMParser`); without one (server-side rendering) the tree is empty, never the input.
10
+ */
11
+ /** The longest plain-text description the server takes, in characters (it allows a little more; this is the bound the dialog holds itself to). */
12
+ export declare const MAX_EVENT_DESCRIPTION_LENGTH = 32000;
13
+ /** The longest description HTML the server takes, in characters. */
14
+ export declare const MAX_EVENT_DESCRIPTION_HTML_LENGTH = 64000;
15
+ /** The elements a description may hold (`b`/`i` are kept as `strong`/`em`). */
16
+ export type DescriptionTag = "strong" | "em" | "u" | "br" | "p" | "ul" | "ol" | "li" | "a";
17
+ export type DescriptionNode = {
18
+ text: string;
19
+ } | {
20
+ tag: DescriptionTag;
21
+ href?: string;
22
+ children: DescriptionNode[];
23
+ };
24
+ /**
25
+ * `href` as a link a description may carry - an absolute `http`, `https` or `mailto` URL, in its canonical form - or `undefined` for anything else
26
+ * (`javascript:`, `data:`, a relative link, a URL with a control character in it). Whitespace and control characters are removed first, since a browser
27
+ * ignores them inside a scheme (`java\tscript:`).
28
+ */
29
+ export declare function safeDescriptionHref(href: string | null | undefined): string | undefined;
30
+ /** The elements and text of `html` a description may hold, and nothing else. `[]` without a DOM. */
31
+ export declare function parseEventDescription(html: string | null | undefined): DescriptionNode[];
32
+ /**
33
+ * `html` reduced to what a description may hold, written as canonical HTML (a link with `rel="noopener noreferrer"`, text and attribute values escaped,
34
+ * every tag closed) and without the empty paragraphs an editor leaves before and after the text - a description with no text in it is `""`. Idempotent.
35
+ * This is what the dialog sends; the server sanitizes it again. `""` without a DOM.
36
+ */
37
+ export declare function sanitizeEventDescriptionHtml(html: string | null | undefined): string;
38
+ /**
39
+ * The plain text of `html`, as the server derives it: a line break for each `<br>`, paragraph and list item (`- ` before a bulleted item, `1. ` before a
40
+ * numbered one), a link's URL in parentheses after its text when the text is not the URL already, every other tag dropped, whitespace collapsed and runs of
41
+ * blank lines shortened. `""` for a description with no text in it, and without a DOM.
42
+ */
43
+ export declare function htmlToPlainText(html: string | null | undefined): string;