@rapidmx/web-client 0.21.0 → 0.22.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.
- package/README.md +48 -14
- package/apps/admin/_layout.tsx +2 -2
- package/apps/admin/audit-log/index.tsx +4 -4
- package/apps/admin/branding/index.tsx +3 -3
- package/apps/admin/data-requests/index.tsx +8 -8
- package/apps/admin/distribution-lists/[uid].tsx +3 -3
- package/apps/admin/distribution-lists/index.tsx +4 -4
- package/apps/admin/distribution-lists/new/index.tsx +5 -5
- package/apps/admin/domains/[uid].tsx +6 -6
- package/apps/admin/domains/index.tsx +4 -4
- package/apps/admin/domains/new/index.tsx +5 -5
- package/apps/admin/encryption-policy/index.tsx +1 -1
- package/apps/admin/escrow-scopes/[uid].tsx +7 -7
- package/apps/admin/escrow-scopes/index.tsx +4 -4
- package/apps/admin/escrow-scopes/new/index.tsx +5 -5
- package/apps/admin/index.tsx +6 -6
- package/apps/admin/ingest-queue/index.tsx +4 -4
- package/apps/admin/mailbox-policy/index.tsx +1 -1
- package/apps/admin/mailboxes/[uid].tsx +5 -5
- package/apps/admin/quarantine/index.tsx +5 -5
- package/apps/admin/retention-policy/index.tsx +3 -3
- package/apps/admin/signing-certificates/index.tsx +5 -5
- package/apps/admin/transport-rules/[uid].tsx +5 -5
- package/apps/admin/transport-rules/_transportRuleConfig.tsx +3 -3
- package/apps/admin/transport-rules/index.tsx +4 -4
- package/apps/admin/transport-rules/new/index.tsx +5 -5
- package/apps/escrow/_layout.tsx +1 -1
- package/apps/escrow/audit-log/index.tsx +4 -4
- package/apps/escrow/index.tsx +4 -4
- package/apps/escrow/matters/[uid].tsx +10 -10
- package/apps/escrow/matters/new/index.tsx +6 -6
- package/apps/shared/appearance/AppearanceForm.tsx +3 -3
- package/apps/shared/appearance/AppearanceHead.tsx +1 -1
- package/apps/shared/appearance/AppearanceProvider.tsx +3 -3
- package/apps/shared/appearance/appearanceCache.ts +1 -1
- package/apps/shared/appearance/appearanceContext.ts +1 -1
- package/apps/shared/appearance/theme.ts +1 -1
- package/apps/shared/auth/adminAccess.ts +1 -1
- package/apps/shared/calendar/bookingPlugin.ts +1 -1
- package/apps/shared/calendar/calendarLiveUpdates.ts +1 -1
- package/apps/shared/calendar/calendarReminders.ts +1 -1
- package/apps/shared/calendar/useCalendarReminders.ts +1 -1
- package/apps/shared/components/admin/diagnostics/DiagnosticsManager.tsx +1 -1
- package/apps/shared/components/admin/diagnostics/InstalledPlugins.tsx +2 -2
- package/apps/shared/components/admin/diagnostics/LogsPanel.tsx +2 -2
- package/apps/shared/components/admin/diagnostics/PackagesTable.tsx +1 -1
- package/apps/shared/components/admin/diagnostics/RuntimePanel.tsx +1 -1
- package/apps/shared/components/admin/diagnostics/SystemPanel.tsx +2 -2
- package/apps/shared/components/admin/diagnostics/VersionsPanel.tsx +1 -1
- package/apps/shared/components/admin/diagnostics/diagnosticsApi.ts +1 -1
- package/apps/shared/components/admin/diagnostics/format.ts +1 -1
- package/apps/shared/components/admin/diagnostics/logClient.ts +1 -1
- package/apps/shared/components/admin/distributionLists/MemberListCard.tsx +4 -4
- package/apps/shared/components/admin/elevation.ts +1 -1
- package/apps/shared/components/admin/escrowScopes/EscrowScopeKeyAndHoldersFields.tsx +3 -3
- package/apps/shared/components/admin/layout/AdminShell.tsx +8 -8
- package/apps/shared/components/admin/mailboxes/EraseLeftoverDataDialog.tsx +6 -6
- package/apps/shared/components/admin/mailboxes/EscrowScopeCard.tsx +10 -8
- package/apps/shared/components/admin/mailboxes/LeftoverMailboxesSection.tsx +4 -4
- package/apps/shared/components/admin/mailboxes/MailboxTable.tsx +1 -1
- package/apps/shared/components/admin/mailboxes/ResourceSettingsCard.tsx +19 -14
- package/apps/shared/components/admin/mailboxes/ShareAccessCard.tsx +5 -5
- package/apps/shared/components/admin/settings/BrandingForm.tsx +5 -5
- package/apps/shared/components/admin/settings/DomainDnsSetup.tsx +5 -5
- package/apps/shared/components/admin/settings/EncryptionPolicyForm.tsx +4 -4
- package/apps/shared/components/admin/settings/LoadedSettingsForm.tsx +2 -2
- package/apps/shared/components/admin/settings/MailboxCreateForm.tsx +32 -27
- package/apps/shared/components/admin/settings/MailboxPolicyForm.tsx +4 -4
- package/apps/shared/components/admin/settings/PluginsManager.tsx +5 -5
- package/apps/shared/components/admin/settings/RetentionPolicyForm.tsx +5 -5
- package/apps/shared/components/admin/setup/EscrowSetupStep.tsx +7 -7
- package/apps/shared/components/admin/setup/SetupWizard.tsx +27 -23
- package/apps/shared/components/admin/signOut.ts +1 -1
- package/apps/shared/components/admin/usePagedList.tsx +2 -2
- package/apps/shared/components/calendar/AppointmentQuickForm.tsx +3 -3
- package/apps/shared/components/calendar/CalendarListSidebar.tsx +3 -3
- package/apps/shared/components/calendar/DescriptionEditor.tsx +1 -1
- package/apps/shared/components/calendar/EventDescriptionView.tsx +1 -1
- package/apps/shared/components/calendar/EventDetails.tsx +16 -14
- package/apps/shared/components/calendar/EventEditor.tsx +54 -39
- package/apps/shared/components/calendar/EventExpandedForm.tsx +3 -3
- package/apps/shared/components/calendar/EventFormParts.tsx +2 -2
- package/apps/shared/components/calendar/EventModal.tsx +5 -5
- package/apps/shared/components/calendar/EventQuickForm.tsx +3 -3
- package/apps/shared/components/calendar/EventShell.tsx +1 -1
- package/apps/shared/components/calendar/FindATime.tsx +6 -4
- package/apps/shared/components/calendar/GuestInput.tsx +2 -2
- package/apps/shared/components/calendar/MonthView.tsx +2 -2
- package/apps/shared/components/calendar/QuickCreateFaces.tsx +1 -1
- package/apps/shared/components/calendar/QuickFaceFrame.tsx +1 -1
- package/apps/shared/components/calendar/RecurrenceEditor.tsx +2 -2
- package/apps/shared/components/calendar/RequestChangeForm.tsx +8 -6
- package/apps/shared/components/calendar/ResourcePicker.tsx +7 -5
- package/apps/shared/components/calendar/SplitDayView.tsx +1 -1
- package/apps/shared/components/calendar/TaskQuickForm.tsx +23 -18
- package/apps/shared/components/calendar/TimeGridView.tsx +2 -2
- package/apps/shared/components/calendar/allDay.ts +2 -2
- package/apps/shared/components/calendar/eventDialogFields.ts +3 -3
- package/apps/shared/components/calendar/eventForm.ts +3 -3
- package/apps/shared/components/calendar/eventFormat.ts +3 -3
- package/apps/shared/components/calendar/findTimeGrid.ts +2 -2
- package/apps/shared/components/calendar/layout/CalendarShell.tsx +11 -9
- package/apps/shared/components/contacts/ContactDetailPane.tsx +4 -4
- package/apps/shared/components/contacts/ContactForm.tsx +27 -17
- package/apps/shared/components/contacts/ContactsSidebar.tsx +7 -5
- package/apps/shared/components/contacts/KeyChangeReview.tsx +5 -5
- package/apps/shared/components/contacts/contactKeys.ts +3 -3
- package/apps/shared/components/contacts/layout/ContactsShell.tsx +9 -7
- package/apps/shared/components/escrow/layout/EscrowShell.tsx +6 -6
- package/apps/shared/components/forms/StringListField.tsx +1 -1
- package/apps/shared/components/layout/AppShell.tsx +12 -10
- package/apps/shared/components/layout/BrandingChrome.tsx +1 -1
- package/apps/shared/components/layout/KeyEnrollmentGate.tsx +9 -9
- package/apps/shared/components/layout/MailboxProvisioning.tsx +8 -6
- package/apps/shared/components/layout/RecoveryCodeUnlock.tsx +9 -9
- package/apps/shared/components/layout/ThemeSwitch.tsx +1 -1
- package/apps/shared/components/layout/UnlockPromptProvider.tsx +6 -6
- package/apps/shared/components/layout/UserMenu.tsx +6 -4
- package/apps/shared/components/mail/ConversationList.tsx +7 -5
- package/apps/shared/components/mail/ConversationThreadPane.tsx +26 -15
- package/apps/shared/components/mail/InviteCard.tsx +11 -9
- package/apps/shared/components/mail/LazyReadingPane.tsx +2 -2
- package/apps/shared/components/mail/MailAddress.tsx +1 -1
- package/apps/shared/components/mail/MailListToolbar.tsx +2 -2
- package/apps/shared/components/mail/MailSelectionBar.tsx +2 -2
- package/apps/shared/components/mail/MenuButton.tsx +1 -1
- package/apps/shared/components/mail/MessageDetailPane.tsx +32 -30
- package/apps/shared/components/mail/MoveToFolderDialog.tsx +8 -6
- package/apps/shared/components/mail/OutboxRowStatus.tsx +1 -1
- package/apps/shared/components/mail/PermanentDeleteDialog.tsx +2 -2
- package/apps/shared/components/mail/compose/ComposeContext.tsx +14 -3
- package/apps/shared/components/mail/compose/ComposeWindow.tsx +34 -30
- package/apps/shared/components/mail/compose/ComposeWindowPlaceholder.tsx +4 -4
- package/apps/shared/components/mail/compose/EmojiPicker.tsx +2 -2
- package/apps/shared/components/mail/compose/GifPicker.tsx +3 -3
- package/apps/shared/components/mail/compose/RecipientInput.tsx +1 -1
- package/apps/shared/components/mail/compose/ScheduleSendPicker.tsx +1 -1
- package/apps/shared/components/mail/compose/encryptionRequirement.ts +2 -2
- package/apps/shared/components/mail/compose/quotedBody.ts +5 -5
- package/apps/shared/components/mail/compose/recipients.ts +1 -1
- package/apps/shared/components/mail/invite/InviteRowChip.tsx +2 -2
- package/apps/shared/components/mail/invite/InviteRsvpPopover.tsx +9 -7
- package/apps/shared/components/mail/invite/InviteTimeline.tsx +1 -1
- package/apps/shared/components/mail/invite/ProposeTimeForm.tsx +2 -2
- package/apps/shared/components/mail/invite/inviteFormat.ts +2 -2
- package/apps/shared/components/mail/invite/inviteStore.ts +14 -6
- package/apps/shared/components/mail/labelMenu.tsx +9 -7
- package/apps/shared/components/mail/layout/MailShell.tsx +4 -4
- package/apps/shared/components/mail/listPreferences.ts +2 -2
- package/apps/shared/components/mail/pinnedSigners.ts +45 -19
- package/apps/shared/components/mail/reading/EncryptedBody.tsx +2 -2
- package/apps/shared/components/mail/reading/MessageBody.tsx +6 -6
- package/apps/shared/components/mail/reading/MessageCard.tsx +3 -3
- package/apps/shared/components/mail/reading/MessageSourceDialog.tsx +3 -3
- package/apps/shared/components/mail/reading/PendingMessageCard.tsx +1 -1
- package/apps/shared/components/mail/reading/bodyContent.ts +3 -3
- package/apps/shared/components/mail/reading/bodyHtml.ts +1 -1
- package/apps/shared/components/mail/reading/messageExport.ts +1 -1
- package/apps/shared/components/mail/reading/printMessage.ts +2 -2
- package/apps/shared/components/mail/reading/useMessageActions.ts +28 -21
- package/apps/shared/components/mail/unreadStyle.tsx +1 -1
- package/apps/shared/components/mail/verificationSeals.ts +16 -12
- package/apps/shared/components/mail/writableMailboxes.ts +14 -7
- package/apps/shared/components/rules/RuleBuilder.tsx +1 -1
- package/apps/shared/components/settings/SigningCertificateCard.tsx +4 -4
- package/apps/shared/components/settings/layout/SettingsShell.tsx +8 -6
- package/apps/shared/components/sharing/PrincipalListField.tsx +1 -1
- package/apps/shared/components/sharing/PrincipalPicker.tsx +1 -1
- package/apps/shared/components/sharing/PrincipalResolver.tsx +4 -4
- package/apps/shared/components/tasks/TasksSidebar.tsx +7 -5
- package/apps/shared/components/tasks/layout/TasksShell.tsx +9 -7
- package/apps/shared/keyboard/ShortcutsDialog.tsx +1 -1
- package/apps/shared/mail/findWellKnownFolderUid.ts +6 -4
- package/apps/shared/mail/folderCounts.ts +8 -4
- package/apps/shared/mail/folderOfType.ts +5 -3
- package/apps/shared/mail/folderTree.ts +1 -1
- package/apps/shared/mail/listSnapshots.ts +2 -2
- package/apps/shared/mail/messageReadState.ts +6 -5
- package/apps/shared/mail/newMailNotifications.ts +2 -2
- package/apps/shared/mail/outbox/composeBridge.ts +2 -2
- package/apps/shared/mail/outbox/outboxState.ts +1 -1
- package/apps/shared/mail/outbox/outgoingReplies.ts +2 -2
- package/apps/shared/mail/outbox/sendDecision.ts +2 -2
- package/apps/shared/mail/outbox/sendJob.ts +40 -35
- package/apps/shared/mail/outbox/sendOutcomes.ts +20 -15
- package/apps/shared/mail/outbox/useOutboxStatus.ts +5 -3
- package/apps/shared/mail/permanentDelete.ts +8 -7
- package/apps/shared/mail/primaryMailbox.ts +1 -1
- package/apps/shared/mail/reportNotices.ts +1 -1
- package/apps/shared/mail/senderBlocking.ts +36 -20
- package/apps/shared/mail/useMailConnection.ts +12 -10
- package/apps/shared/mail/useMailLiveUpdates.ts +3 -3
- package/apps/shared/mail/useMailboxUpdateAccess.ts +35 -11
- package/apps/shared/mail/useMarkMessageRead.ts +14 -7
- package/apps/shared/mail/useNewMailNotifications.ts +1 -1
- package/apps/shared/mail/usePermanentDelete.tsx +5 -3
- package/apps/shared/navigation/pageTitle.ts +1 -1
- package/apps/shared/notifications/NotificationCenter.tsx +1 -1
- package/apps/shared/notifications/NotificationHistoryDialog.tsx +2 -2
- package/apps/shared/notifications/apiErrors.ts +2 -2
- package/apps/shared/notifications/pushStatus.ts +1 -1
- package/apps/shared/notifications/systemErrors.ts +1 -1
- package/apps/shared/search/LocalIndexLifecycle.tsx +18 -12
- package/apps/shared/search/crossMailboxSearch.ts +3 -3
- package/apps/shared/search/localIndexBuilder.ts +24 -12
- package/apps/shared/search/localIndexKey.ts +1 -1
- package/apps/shared/search/localIndexRpcClient.ts +150 -30
- package/apps/shared/search/localIndexTransport.ts +84 -0
- package/apps/shared/search/localIndexWorker.ts +1 -1
- package/apps/shared/search/searchTier2.ts +3 -3
- package/apps/shared/signing/enrollmentTracker.ts +3 -3
- package/apps/shared/signing/enrollmentView.ts +1 -1
- package/apps/shared/signing/signingInfo.ts +1 -1
- package/apps/shared/signing/useSigningEnrollmentWatcher.ts +6 -4
- package/apps/shared/styles/app.css +14 -23
- package/apps/www/_layout.tsx +2 -2
- package/apps/www/calendar/index.tsx +20 -18
- package/apps/www/contacts/[uid].tsx +8 -6
- package/apps/www/contacts/index.tsx +19 -17
- package/apps/www/index.tsx +57 -48
- package/apps/www/messages/[uid].tsx +11 -9
- package/apps/www/settings/auto-reply/index.tsx +6 -4
- package/apps/www/settings/blocked-senders/index.tsx +9 -7
- package/apps/www/settings/encryption/index.tsx +38 -32
- package/apps/www/settings/filters/[uid].tsx +19 -14
- package/apps/www/settings/filters/_mailFilterRuleConfig.tsx +2 -2
- package/apps/www/settings/filters/index.tsx +4 -4
- package/apps/www/settings/filters/new/index.tsx +10 -8
- package/apps/www/settings/labels/index.tsx +12 -10
- package/apps/www/settings/privacy/index.tsx +18 -14
- package/apps/www/settings/profile/index.tsx +16 -11
- package/apps/www/settings/read-receipts/index.tsx +17 -12
- package/apps/www/settings/sharing/index.tsx +6 -6
- package/apps/www/settings/signatures/[uid].tsx +5 -5
- package/apps/www/settings/signatures/index.tsx +4 -4
- package/apps/www/settings/signatures/new/index.tsx +4 -4
- package/apps/www/settings/signatures/signatureDefaults.ts +1 -1
- package/apps/www/tasks/index.tsx +28 -23
- package/dist/apps/admin/_layout.d.ts +1 -1
- package/dist/apps/admin/_layout.js +1 -1
- package/dist/apps/admin/audit-log/index.d.ts +1 -1
- package/dist/apps/admin/audit-log/index.js +4 -4
- package/dist/apps/admin/branding/index.js +3 -3
- package/dist/apps/admin/data-requests/index.js +8 -8
- package/dist/apps/admin/distribution-lists/[uid].js +3 -3
- package/dist/apps/admin/distribution-lists/index.js +4 -4
- package/dist/apps/admin/distribution-lists/new/index.js +5 -5
- package/dist/apps/admin/domains/[uid].js +6 -6
- package/dist/apps/admin/domains/index.js +4 -4
- package/dist/apps/admin/domains/new/index.js +5 -5
- package/dist/apps/admin/encryption-policy/index.js +1 -1
- package/dist/apps/admin/escrow-scopes/[uid].d.ts +1 -1
- package/dist/apps/admin/escrow-scopes/[uid].js +7 -7
- package/dist/apps/admin/escrow-scopes/index.js +4 -4
- package/dist/apps/admin/escrow-scopes/new/index.js +5 -5
- package/dist/apps/admin/index.js +6 -6
- package/dist/apps/admin/ingest-queue/index.js +4 -4
- package/dist/apps/admin/mailbox-policy/index.js +1 -1
- package/dist/apps/admin/mailboxes/[uid].js +5 -5
- package/dist/apps/admin/quarantine/index.js +5 -5
- package/dist/apps/admin/retention-policy/index.js +3 -3
- package/dist/apps/admin/signing-certificates/index.js +5 -5
- package/dist/apps/admin/transport-rules/[uid].js +5 -5
- package/dist/apps/admin/transport-rules/_transportRuleConfig.d.ts +1 -1
- package/dist/apps/admin/transport-rules/_transportRuleConfig.js +2 -2
- package/dist/apps/admin/transport-rules/index.js +4 -4
- package/dist/apps/admin/transport-rules/new/index.js +5 -5
- package/dist/apps/escrow/_layout.d.ts +1 -1
- package/dist/apps/escrow/audit-log/index.d.ts +1 -1
- package/dist/apps/escrow/audit-log/index.js +4 -4
- package/dist/apps/escrow/index.js +4 -4
- package/dist/apps/escrow/matters/[uid].js +10 -10
- package/dist/apps/escrow/matters/new/index.js +6 -6
- package/dist/apps/shared/appearance/AppearanceForm.js +3 -3
- package/dist/apps/shared/appearance/AppearanceHead.js +1 -1
- package/dist/apps/shared/appearance/AppearanceProvider.d.ts +1 -1
- package/dist/apps/shared/appearance/AppearanceProvider.js +3 -3
- package/dist/apps/shared/appearance/appearanceCache.d.ts +1 -1
- package/dist/apps/shared/appearance/appearanceCache.js +1 -1
- package/dist/apps/shared/appearance/appearanceContext.d.ts +1 -1
- package/dist/apps/shared/appearance/theme.d.ts +1 -1
- package/dist/apps/shared/auth/adminAccess.js +1 -1
- package/dist/apps/shared/calendar/bookingPlugin.js +1 -1
- package/dist/apps/shared/calendar/calendarLiveUpdates.d.ts +1 -1
- package/dist/apps/shared/calendar/calendarReminders.d.ts +1 -1
- package/dist/apps/shared/calendar/useCalendarReminders.js +1 -1
- package/dist/apps/shared/components/admin/diagnostics/DiagnosticsManager.js +1 -1
- package/dist/apps/shared/components/admin/diagnostics/InstalledPlugins.d.ts +1 -1
- package/dist/apps/shared/components/admin/diagnostics/InstalledPlugins.js +2 -2
- package/dist/apps/shared/components/admin/diagnostics/LogsPanel.js +2 -2
- package/dist/apps/shared/components/admin/diagnostics/PackagesTable.js +1 -1
- package/dist/apps/shared/components/admin/diagnostics/RuntimePanel.js +1 -1
- package/dist/apps/shared/components/admin/diagnostics/SystemPanel.js +2 -2
- package/dist/apps/shared/components/admin/diagnostics/VersionsPanel.js +1 -1
- package/dist/apps/shared/components/admin/diagnostics/diagnosticsApi.js +1 -1
- package/dist/apps/shared/components/admin/diagnostics/format.js +1 -1
- package/dist/apps/shared/components/admin/diagnostics/logClient.js +1 -1
- package/dist/apps/shared/components/admin/distributionLists/MemberListCard.d.ts +1 -1
- package/dist/apps/shared/components/admin/distributionLists/MemberListCard.js +4 -4
- package/dist/apps/shared/components/admin/elevation.js +1 -1
- package/dist/apps/shared/components/admin/escrowScopes/EscrowScopeKeyAndHoldersFields.js +3 -3
- package/dist/apps/shared/components/admin/layout/AdminShell.d.ts +1 -1
- package/dist/apps/shared/components/admin/layout/AdminShell.js +7 -7
- package/dist/apps/shared/components/admin/mailboxes/EraseLeftoverDataDialog.d.ts +1 -1
- package/dist/apps/shared/components/admin/mailboxes/EraseLeftoverDataDialog.js +6 -6
- package/dist/apps/shared/components/admin/mailboxes/EscrowScopeCard.d.ts +1 -1
- package/dist/apps/shared/components/admin/mailboxes/EscrowScopeCard.js +10 -8
- package/dist/apps/shared/components/admin/mailboxes/LeftoverMailboxesSection.js +4 -4
- package/dist/apps/shared/components/admin/mailboxes/MailboxTable.d.ts +1 -1
- package/dist/apps/shared/components/admin/mailboxes/ResourceSettingsCard.d.ts +1 -1
- package/dist/apps/shared/components/admin/mailboxes/ResourceSettingsCard.js +7 -5
- package/dist/apps/shared/components/admin/mailboxes/ShareAccessCard.js +5 -5
- package/dist/apps/shared/components/admin/settings/BrandingForm.d.ts +1 -1
- package/dist/apps/shared/components/admin/settings/BrandingForm.js +5 -5
- package/dist/apps/shared/components/admin/settings/DomainDnsSetup.d.ts +1 -1
- package/dist/apps/shared/components/admin/settings/DomainDnsSetup.js +5 -5
- package/dist/apps/shared/components/admin/settings/EncryptionPolicyForm.d.ts +1 -1
- package/dist/apps/shared/components/admin/settings/EncryptionPolicyForm.js +4 -4
- package/dist/apps/shared/components/admin/settings/LoadedSettingsForm.js +2 -2
- package/dist/apps/shared/components/admin/settings/MailboxCreateForm.d.ts +1 -1
- package/dist/apps/shared/components/admin/settings/MailboxCreateForm.js +14 -12
- package/dist/apps/shared/components/admin/settings/MailboxPolicyForm.d.ts +1 -1
- package/dist/apps/shared/components/admin/settings/MailboxPolicyForm.js +4 -4
- package/dist/apps/shared/components/admin/settings/PluginsManager.js +5 -5
- package/dist/apps/shared/components/admin/settings/RetentionPolicyForm.d.ts +1 -1
- package/dist/apps/shared/components/admin/settings/RetentionPolicyForm.js +5 -5
- package/dist/apps/shared/components/admin/setup/EscrowSetupStep.js +7 -7
- package/dist/apps/shared/components/admin/setup/SetupWizard.js +26 -22
- package/dist/apps/shared/components/admin/signOut.js +1 -1
- package/dist/apps/shared/components/admin/usePagedList.js +2 -2
- package/dist/apps/shared/components/calendar/AppointmentQuickForm.js +3 -3
- package/dist/apps/shared/components/calendar/CalendarListSidebar.d.ts +1 -1
- package/dist/apps/shared/components/calendar/CalendarListSidebar.js +2 -2
- package/dist/apps/shared/components/calendar/DescriptionEditor.js +1 -1
- package/dist/apps/shared/components/calendar/EventDescriptionView.js +1 -1
- package/dist/apps/shared/components/calendar/EventDetails.d.ts +2 -2
- package/dist/apps/shared/components/calendar/EventDetails.js +16 -14
- package/dist/apps/shared/components/calendar/EventEditor.d.ts +2 -2
- package/dist/apps/shared/components/calendar/EventEditor.js +22 -20
- package/dist/apps/shared/components/calendar/EventExpandedForm.js +2 -2
- package/dist/apps/shared/components/calendar/EventFormParts.d.ts +1 -1
- package/dist/apps/shared/components/calendar/EventFormParts.js +1 -1
- package/dist/apps/shared/components/calendar/EventModal.d.ts +2 -2
- package/dist/apps/shared/components/calendar/EventModal.js +3 -3
- package/dist/apps/shared/components/calendar/EventQuickForm.js +3 -3
- package/dist/apps/shared/components/calendar/EventShell.js +1 -1
- package/dist/apps/shared/components/calendar/FindATime.js +6 -4
- package/dist/apps/shared/components/calendar/GuestInput.d.ts +2 -2
- package/dist/apps/shared/components/calendar/MonthView.d.ts +1 -1
- package/dist/apps/shared/components/calendar/MonthView.js +1 -1
- package/dist/apps/shared/components/calendar/QuickCreateFaces.js +1 -1
- package/dist/apps/shared/components/calendar/QuickFaceFrame.js +1 -1
- package/dist/apps/shared/components/calendar/RecurrenceEditor.d.ts +1 -1
- package/dist/apps/shared/components/calendar/RecurrenceEditor.js +1 -1
- package/dist/apps/shared/components/calendar/RequestChangeForm.js +8 -6
- package/dist/apps/shared/components/calendar/ResourcePicker.d.ts +1 -1
- package/dist/apps/shared/components/calendar/ResourcePicker.js +7 -5
- package/dist/apps/shared/components/calendar/SplitDayView.d.ts +1 -1
- package/dist/apps/shared/components/calendar/TaskQuickForm.d.ts +1 -1
- package/dist/apps/shared/components/calendar/TaskQuickForm.js +9 -7
- package/dist/apps/shared/components/calendar/TimeGridView.d.ts +1 -1
- package/dist/apps/shared/components/calendar/TimeGridView.js +1 -1
- package/dist/apps/shared/components/calendar/allDay.d.ts +2 -2
- package/dist/apps/shared/components/calendar/allDay.js +1 -1
- package/dist/apps/shared/components/calendar/eventDialogFields.d.ts +2 -2
- package/dist/apps/shared/components/calendar/eventDialogFields.js +2 -2
- package/dist/apps/shared/components/calendar/eventForm.d.ts +3 -3
- package/dist/apps/shared/components/calendar/eventFormat.d.ts +1 -1
- package/dist/apps/shared/components/calendar/eventFormat.js +2 -2
- package/dist/apps/shared/components/calendar/findTimeGrid.d.ts +1 -1
- package/dist/apps/shared/components/calendar/findTimeGrid.js +1 -1
- package/dist/apps/shared/components/calendar/layout/CalendarShell.d.ts +1 -1
- package/dist/apps/shared/components/calendar/layout/CalendarShell.js +11 -9
- package/dist/apps/shared/components/contacts/ContactDetailPane.d.ts +1 -1
- package/dist/apps/shared/components/contacts/ContactDetailPane.js +2 -2
- package/dist/apps/shared/components/contacts/ContactForm.d.ts +2 -2
- package/dist/apps/shared/components/contacts/ContactForm.js +12 -8
- package/dist/apps/shared/components/contacts/ContactsSidebar.d.ts +1 -1
- package/dist/apps/shared/components/contacts/ContactsSidebar.js +7 -5
- package/dist/apps/shared/components/contacts/KeyChangeReview.d.ts +1 -1
- package/dist/apps/shared/components/contacts/KeyChangeReview.js +5 -5
- package/dist/apps/shared/components/contacts/contactKeys.d.ts +2 -2
- package/dist/apps/shared/components/contacts/contactKeys.js +2 -2
- package/dist/apps/shared/components/contacts/layout/ContactsShell.d.ts +1 -1
- package/dist/apps/shared/components/contacts/layout/ContactsShell.js +9 -7
- package/dist/apps/shared/components/escrow/layout/EscrowShell.js +6 -6
- package/dist/apps/shared/components/forms/StringListField.js +1 -1
- package/dist/apps/shared/components/layout/AppShell.d.ts +2 -2
- package/dist/apps/shared/components/layout/AppShell.js +11 -9
- package/dist/apps/shared/components/layout/BrandingChrome.d.ts +1 -1
- package/dist/apps/shared/components/layout/KeyEnrollmentGate.d.ts +1 -1
- package/dist/apps/shared/components/layout/KeyEnrollmentGate.js +9 -9
- package/dist/apps/shared/components/layout/MailboxProvisioning.js +8 -6
- package/dist/apps/shared/components/layout/RecoveryCodeUnlock.d.ts +1 -1
- package/dist/apps/shared/components/layout/RecoveryCodeUnlock.js +9 -9
- package/dist/apps/shared/components/layout/UnlockPromptProvider.d.ts +2 -2
- package/dist/apps/shared/components/layout/UnlockPromptProvider.js +5 -5
- package/dist/apps/shared/components/layout/UserMenu.js +6 -4
- package/dist/apps/shared/components/mail/ConversationList.d.ts +2 -2
- package/dist/apps/shared/components/mail/ConversationList.js +6 -4
- package/dist/apps/shared/components/mail/ConversationThreadPane.d.ts +3 -3
- package/dist/apps/shared/components/mail/ConversationThreadPane.js +13 -11
- package/dist/apps/shared/components/mail/InviteCard.js +10 -8
- package/dist/apps/shared/components/mail/LazyReadingPane.js +2 -2
- package/dist/apps/shared/components/mail/MailAddress.d.ts +1 -1
- package/dist/apps/shared/components/mail/MailAddress.js +1 -1
- package/dist/apps/shared/components/mail/MailListToolbar.d.ts +2 -2
- package/dist/apps/shared/components/mail/MailSelectionBar.d.ts +2 -2
- package/dist/apps/shared/components/mail/MenuButton.js +1 -1
- package/dist/apps/shared/components/mail/MessageDetailPane.d.ts +3 -3
- package/dist/apps/shared/components/mail/MessageDetailPane.js +30 -28
- package/dist/apps/shared/components/mail/MoveToFolderDialog.d.ts +1 -1
- package/dist/apps/shared/components/mail/MoveToFolderDialog.js +8 -6
- package/dist/apps/shared/components/mail/OutboxRowStatus.d.ts +1 -1
- package/dist/apps/shared/components/mail/PermanentDeleteDialog.js +2 -2
- package/dist/apps/shared/components/mail/compose/ComposeContext.d.ts +10 -1
- package/dist/apps/shared/components/mail/compose/ComposeContext.js +4 -2
- package/dist/apps/shared/components/mail/compose/ComposeWindow.js +34 -30
- package/dist/apps/shared/components/mail/compose/ComposeWindowPlaceholder.js +4 -4
- package/dist/apps/shared/components/mail/compose/EmojiPicker.js +2 -2
- package/dist/apps/shared/components/mail/compose/GifPicker.js +3 -3
- package/dist/apps/shared/components/mail/compose/RecipientInput.d.ts +1 -1
- package/dist/apps/shared/components/mail/compose/RecipientInput.js +1 -1
- package/dist/apps/shared/components/mail/compose/ScheduleSendPicker.js +1 -1
- package/dist/apps/shared/components/mail/compose/encryptionRequirement.d.ts +2 -2
- package/dist/apps/shared/components/mail/compose/encryptionRequirement.js +1 -1
- package/dist/apps/shared/components/mail/compose/quotedBody.d.ts +3 -3
- package/dist/apps/shared/components/mail/compose/quotedBody.js +3 -3
- package/dist/apps/shared/components/mail/compose/recipients.d.ts +1 -1
- package/dist/apps/shared/components/mail/invite/InviteRowChip.d.ts +1 -1
- package/dist/apps/shared/components/mail/invite/InviteRsvpPopover.d.ts +1 -1
- package/dist/apps/shared/components/mail/invite/InviteRsvpPopover.js +9 -7
- package/dist/apps/shared/components/mail/invite/InviteTimeline.d.ts +1 -1
- package/dist/apps/shared/components/mail/invite/ProposeTimeForm.d.ts +1 -1
- package/dist/apps/shared/components/mail/invite/ProposeTimeForm.js +1 -1
- package/dist/apps/shared/components/mail/invite/inviteFormat.d.ts +2 -2
- package/dist/apps/shared/components/mail/invite/inviteStore.d.ts +9 -3
- package/dist/apps/shared/components/mail/invite/inviteStore.js +13 -6
- package/dist/apps/shared/components/mail/labelMenu.d.ts +1 -1
- package/dist/apps/shared/components/mail/labelMenu.js +9 -7
- package/dist/apps/shared/components/mail/layout/MailShell.d.ts +1 -1
- package/dist/apps/shared/components/mail/layout/MailShell.js +3 -3
- package/dist/apps/shared/components/mail/listPreferences.d.ts +2 -2
- package/dist/apps/shared/components/mail/listPreferences.js +1 -1
- package/dist/apps/shared/components/mail/pinnedSigners.d.ts +12 -5
- package/dist/apps/shared/components/mail/pinnedSigners.js +37 -18
- package/dist/apps/shared/components/mail/reading/EncryptedBody.js +2 -2
- package/dist/apps/shared/components/mail/reading/MessageBody.d.ts +2 -2
- package/dist/apps/shared/components/mail/reading/MessageBody.js +4 -4
- package/dist/apps/shared/components/mail/reading/MessageCard.d.ts +1 -1
- package/dist/apps/shared/components/mail/reading/MessageCard.js +2 -2
- package/dist/apps/shared/components/mail/reading/MessageSourceDialog.js +3 -3
- package/dist/apps/shared/components/mail/reading/PendingMessageCard.js +1 -1
- package/dist/apps/shared/components/mail/reading/bodyContent.d.ts +2 -2
- package/dist/apps/shared/components/mail/reading/bodyContent.js +2 -2
- package/dist/apps/shared/components/mail/reading/bodyHtml.js +1 -1
- package/dist/apps/shared/components/mail/reading/messageExport.js +1 -1
- package/dist/apps/shared/components/mail/reading/printMessage.d.ts +2 -2
- package/dist/apps/shared/components/mail/reading/useMessageActions.d.ts +1 -1
- package/dist/apps/shared/components/mail/reading/useMessageActions.js +18 -16
- package/dist/apps/shared/components/mail/unreadStyle.d.ts +1 -1
- package/dist/apps/shared/components/mail/verificationSeals.d.ts +27 -6
- package/dist/apps/shared/components/mail/verificationSeals.js +15 -11
- package/dist/apps/shared/components/mail/writableMailboxes.d.ts +8 -3
- package/dist/apps/shared/components/mail/writableMailboxes.js +12 -6
- package/dist/apps/shared/components/rules/RuleBuilder.js +1 -1
- package/dist/apps/shared/components/settings/SigningCertificateCard.d.ts +1 -1
- package/dist/apps/shared/components/settings/SigningCertificateCard.js +3 -3
- package/dist/apps/shared/components/settings/layout/SettingsShell.d.ts +1 -1
- package/dist/apps/shared/components/settings/layout/SettingsShell.js +8 -6
- package/dist/apps/shared/components/sharing/PrincipalListField.d.ts +1 -1
- package/dist/apps/shared/components/sharing/PrincipalPicker.d.ts +1 -1
- package/dist/apps/shared/components/sharing/PrincipalPicker.js +1 -1
- package/dist/apps/shared/components/sharing/PrincipalResolver.d.ts +1 -1
- package/dist/apps/shared/components/sharing/PrincipalResolver.js +3 -3
- package/dist/apps/shared/components/tasks/TasksSidebar.d.ts +1 -1
- package/dist/apps/shared/components/tasks/TasksSidebar.js +7 -5
- package/dist/apps/shared/components/tasks/layout/TasksShell.d.ts +1 -1
- package/dist/apps/shared/components/tasks/layout/TasksShell.js +9 -7
- package/dist/apps/shared/keyboard/ShortcutsDialog.js +1 -1
- package/dist/apps/shared/mail/findWellKnownFolderUid.d.ts +5 -3
- package/dist/apps/shared/mail/findWellKnownFolderUid.js +5 -4
- package/dist/apps/shared/mail/folderCounts.d.ts +1 -1
- package/dist/apps/shared/mail/folderCounts.js +6 -4
- package/dist/apps/shared/mail/folderOfType.d.ts +3 -2
- package/dist/apps/shared/mail/folderOfType.js +4 -4
- package/dist/apps/shared/mail/folderTree.d.ts +1 -1
- package/dist/apps/shared/mail/listSnapshots.d.ts +2 -2
- package/dist/apps/shared/mail/messageReadState.d.ts +4 -3
- package/dist/apps/shared/mail/messageReadState.js +5 -5
- package/dist/apps/shared/mail/newMailNotifications.d.ts +1 -1
- package/dist/apps/shared/mail/newMailNotifications.js +1 -1
- package/dist/apps/shared/mail/outbox/composeBridge.d.ts +2 -2
- package/dist/apps/shared/mail/outbox/outboxState.d.ts +1 -1
- package/dist/apps/shared/mail/outbox/outgoingReplies.d.ts +2 -2
- package/dist/apps/shared/mail/outbox/sendDecision.d.ts +2 -2
- package/dist/apps/shared/mail/outbox/sendDecision.js +1 -1
- package/dist/apps/shared/mail/outbox/sendJob.d.ts +10 -6
- package/dist/apps/shared/mail/outbox/sendJob.js +39 -35
- package/dist/apps/shared/mail/outbox/sendOutcomes.d.ts +6 -3
- package/dist/apps/shared/mail/outbox/sendOutcomes.js +19 -15
- package/dist/apps/shared/mail/outbox/useOutboxStatus.js +5 -3
- package/dist/apps/shared/mail/permanentDelete.d.ts +4 -3
- package/dist/apps/shared/mail/permanentDelete.js +8 -8
- package/dist/apps/shared/mail/primaryMailbox.d.ts +1 -1
- package/dist/apps/shared/mail/primaryMailbox.js +1 -1
- package/dist/apps/shared/mail/reportNotices.d.ts +1 -1
- package/dist/apps/shared/mail/senderBlocking.d.ts +5 -4
- package/dist/apps/shared/mail/senderBlocking.js +19 -16
- package/dist/apps/shared/mail/useMailConnection.d.ts +1 -1
- package/dist/apps/shared/mail/useMailConnection.js +12 -10
- package/dist/apps/shared/mail/useMailLiveUpdates.d.ts +2 -2
- package/dist/apps/shared/mail/useMailLiveUpdates.js +2 -2
- package/dist/apps/shared/mail/useMailboxUpdateAccess.d.ts +3 -2
- package/dist/apps/shared/mail/useMailboxUpdateAccess.js +31 -10
- package/dist/apps/shared/mail/useMarkMessageRead.d.ts +1 -1
- package/dist/apps/shared/mail/useMarkMessageRead.js +5 -3
- package/dist/apps/shared/mail/useNewMailNotifications.d.ts +1 -1
- package/dist/apps/shared/mail/usePermanentDelete.d.ts +1 -1
- package/dist/apps/shared/mail/usePermanentDelete.js +4 -2
- package/dist/apps/shared/navigation/pageTitle.d.ts +1 -1
- package/dist/apps/shared/notifications/NotificationCenter.js +1 -1
- package/dist/apps/shared/notifications/NotificationHistoryDialog.js +2 -2
- package/dist/apps/shared/notifications/apiErrors.js +2 -2
- package/dist/apps/shared/notifications/pushStatus.js +1 -1
- package/dist/apps/shared/notifications/systemErrors.js +1 -1
- package/dist/apps/shared/search/LocalIndexLifecycle.d.ts +2 -2
- package/dist/apps/shared/search/LocalIndexLifecycle.js +15 -10
- package/dist/apps/shared/search/crossMailboxSearch.d.ts +1 -1
- package/dist/apps/shared/search/crossMailboxSearch.js +2 -2
- package/dist/apps/shared/search/localIndexBuilder.d.ts +4 -3
- package/dist/apps/shared/search/localIndexBuilder.js +15 -12
- package/dist/apps/shared/search/localIndexKey.js +1 -1
- package/dist/apps/shared/search/localIndexRpcClient.d.ts +43 -31
- package/dist/apps/shared/search/localIndexRpcClient.js +113 -20
- package/dist/apps/shared/search/localIndexTransport.d.ts +77 -0
- package/dist/apps/shared/search/localIndexTransport.js +1 -0
- package/dist/apps/shared/search/localIndexWorker.d.ts +1 -1
- package/dist/apps/shared/search/searchTier2.d.ts +3 -3
- package/dist/apps/shared/signing/enrollmentTracker.d.ts +1 -1
- package/dist/apps/shared/signing/enrollmentTracker.js +3 -3
- package/dist/apps/shared/signing/enrollmentView.d.ts +1 -1
- package/dist/apps/shared/signing/signingInfo.d.ts +1 -1
- package/dist/apps/shared/signing/signingInfo.js +1 -1
- package/dist/apps/shared/signing/useSigningEnrollmentWatcher.d.ts +1 -1
- package/dist/apps/shared/signing/useSigningEnrollmentWatcher.js +5 -3
- package/dist/apps/shared/styles/app.css +14 -23
- package/dist/apps/www/_layout.d.ts +1 -1
- package/dist/apps/www/_layout.js +1 -1
- package/dist/apps/www/calendar/index.d.ts +1 -1
- package/dist/apps/www/calendar/index.js +20 -18
- package/dist/apps/www/contacts/[uid].d.ts +1 -1
- package/dist/apps/www/contacts/[uid].js +8 -6
- package/dist/apps/www/contacts/index.d.ts +1 -1
- package/dist/apps/www/contacts/index.js +19 -17
- package/dist/apps/www/index.d.ts +1 -1
- package/dist/apps/www/index.js +54 -50
- package/dist/apps/www/messages/[uid].d.ts +1 -1
- package/dist/apps/www/messages/[uid].js +11 -9
- package/dist/apps/www/settings/appearance/index.d.ts +1 -1
- package/dist/apps/www/settings/auto-reply/index.d.ts +1 -1
- package/dist/apps/www/settings/auto-reply/index.js +6 -4
- package/dist/apps/www/settings/blocked-senders/index.d.ts +1 -1
- package/dist/apps/www/settings/blocked-senders/index.js +6 -4
- package/dist/apps/www/settings/encryption/index.d.ts +1 -1
- package/dist/apps/www/settings/encryption/index.js +31 -29
- package/dist/apps/www/settings/filters/[uid].d.ts +1 -1
- package/dist/apps/www/settings/filters/[uid].js +11 -9
- package/dist/apps/www/settings/filters/_mailFilterRuleConfig.d.ts +2 -2
- package/dist/apps/www/settings/filters/index.d.ts +1 -1
- package/dist/apps/www/settings/filters/index.js +4 -4
- package/dist/apps/www/settings/filters/new/index.d.ts +1 -1
- package/dist/apps/www/settings/filters/new/index.js +10 -8
- package/dist/apps/www/settings/labels/index.d.ts +1 -1
- package/dist/apps/www/settings/labels/index.js +12 -10
- package/dist/apps/www/settings/privacy/index.d.ts +1 -1
- package/dist/apps/www/settings/privacy/index.js +18 -14
- package/dist/apps/www/settings/profile/index.d.ts +1 -1
- package/dist/apps/www/settings/profile/index.js +7 -5
- package/dist/apps/www/settings/read-receipts/index.d.ts +1 -1
- package/dist/apps/www/settings/read-receipts/index.js +5 -3
- package/dist/apps/www/settings/sharing/index.d.ts +1 -1
- package/dist/apps/www/settings/sharing/index.js +6 -6
- package/dist/apps/www/settings/signatures/[uid].d.ts +1 -1
- package/dist/apps/www/settings/signatures/[uid].js +5 -5
- package/dist/apps/www/settings/signatures/index.d.ts +1 -1
- package/dist/apps/www/settings/signatures/index.js +4 -4
- package/dist/apps/www/settings/signatures/new/index.d.ts +1 -1
- package/dist/apps/www/settings/signatures/new/index.js +4 -4
- package/dist/apps/www/settings/signatures/signatureDefaults.d.ts +1 -1
- package/dist/apps/www/settings/signatures/signatureDefaults.js +1 -1
- package/dist/apps/www/tasks/index.d.ts +1 -1
- package/dist/apps/www/tasks/index.js +17 -15
- package/dist/lib/admin/auditLogApi.d.ts +32 -0
- package/dist/lib/admin/auditLogApi.js +27 -0
- package/dist/lib/admin/distributionListsApi.d.ts +47 -0
- package/dist/lib/admin/distributionListsApi.js +34 -0
- package/dist/lib/admin/domainsApi.d.ts +75 -0
- package/dist/lib/admin/domainsApi.js +44 -0
- package/dist/lib/admin/escrowAccessRequestsApi.d.ts +79 -0
- package/dist/lib/admin/escrowAccessRequestsApi.js +46 -0
- package/dist/lib/admin/escrowAuditLogApi.d.ts +66 -0
- package/dist/lib/admin/escrowAuditLogApi.js +31 -0
- package/dist/lib/admin/escrowScopesApi.d.ts +78 -0
- package/dist/lib/admin/escrowScopesApi.js +50 -0
- package/dist/lib/admin/leftoverMailboxApi.d.ts +73 -0
- package/dist/lib/admin/leftoverMailboxApi.js +67 -0
- package/dist/lib/admin/mailboxPolicyApi.d.ts +27 -0
- package/dist/lib/admin/mailboxPolicyApi.js +21 -0
- package/dist/lib/admin/matterExportApi.d.ts +40 -0
- package/dist/lib/admin/matterExportApi.js +39 -0
- package/dist/lib/admin/matterSearchApi.d.ts +20 -0
- package/dist/lib/admin/matterSearchApi.js +27 -0
- package/dist/lib/admin/mattersApi.d.ts +56 -0
- package/dist/lib/admin/mattersApi.js +40 -0
- package/dist/lib/admin/pluginsApi.d.ts +265 -0
- package/dist/lib/admin/pluginsApi.js +102 -0
- package/dist/lib/admin/retentionPolicyApi.d.ts +32 -0
- package/dist/lib/admin/retentionPolicyApi.js +29 -0
- package/dist/lib/admin/setupApi.d.ts +23 -0
- package/dist/lib/admin/setupApi.js +26 -0
- package/dist/lib/admin/transportRulesApi.d.ts +66 -0
- package/dist/lib/admin/transportRulesApi.js +43 -0
- package/dist/lib/appearance/preferencesApi.d.ts +128 -0
- package/dist/lib/appearance/preferencesApi.js +257 -0
- package/dist/lib/auth/profileApi.d.ts +33 -0
- package/dist/lib/auth/profileApi.js +52 -0
- package/dist/lib/auth/session.d.ts +70 -0
- package/dist/lib/auth/session.js +210 -0
- package/dist/lib/branding/brandingApi.d.ts +47 -0
- package/dist/lib/branding/brandingApi.js +61 -0
- package/dist/lib/branding/useBranding.d.ts +23 -0
- package/dist/lib/branding/useBranding.js +65 -0
- package/dist/lib/calendar/calendarApi.d.ts +230 -0
- package/dist/lib/calendar/calendarApi.js +106 -0
- package/dist/lib/calendar/calendarColors.d.ts +18 -0
- package/dist/lib/calendar/calendarColors.js +39 -0
- package/dist/lib/calendar/calendarDragIds.d.ts +42 -0
- package/dist/lib/calendar/calendarDragIds.js +92 -0
- package/dist/lib/calendar/calendarMutations.d.ts +68 -0
- package/dist/lib/calendar/calendarMutations.js +190 -0
- package/dist/lib/calendar/eventDescription.d.ts +43 -0
- package/dist/lib/calendar/eventDescription.js +195 -0
- package/dist/lib/calendar/freeBusyApi.d.ts +100 -0
- package/dist/lib/calendar/freeBusyApi.js +119 -0
- package/dist/lib/calendar/inviteApi.d.ts +121 -0
- package/dist/lib/calendar/inviteApi.js +54 -0
- package/dist/lib/calendar/recurrence.d.ts +60 -0
- package/dist/lib/calendar/recurrence.js +225 -0
- package/dist/lib/components/avatar/ContactAvatar.d.ts +8 -0
- package/dist/lib/components/avatar/ContactAvatar.js +26 -0
- package/dist/lib/components/buttons/Button.d.ts +9 -0
- package/dist/lib/components/buttons/Button.js +14 -0
- package/dist/lib/components/buttons/CopyButton.d.ts +18 -0
- package/dist/lib/components/buttons/CopyButton.js +14 -0
- package/dist/lib/components/feedback/Alert.d.ts +4 -0
- package/dist/lib/components/feedback/Alert.js +4 -0
- package/dist/lib/components/feedback/Skeleton.d.ts +21 -0
- package/dist/lib/components/feedback/Skeleton.js +14 -0
- package/dist/lib/components/forms/FormField.d.ts +8 -0
- package/dist/lib/components/forms/FormField.js +5 -0
- package/dist/lib/components/navigation/BottomTabBar.d.ts +27 -0
- package/dist/lib/components/navigation/BottomTabBar.js +32 -0
- package/dist/lib/components/overlays/Drawer.d.ts +20 -0
- package/dist/lib/components/overlays/Drawer.js +27 -0
- package/dist/lib/components/overlays/Modal.d.ts +17 -0
- package/dist/lib/components/overlays/Modal.js +25 -0
- package/dist/lib/components/overlays/PopoverPortal.d.ts +23 -0
- package/dist/lib/components/overlays/PopoverPortal.js +53 -0
- package/dist/lib/components/overlays/overlayStack.d.ts +31 -0
- package/dist/lib/components/overlays/overlayStack.js +143 -0
- package/dist/lib/components/pickers/MiniDatePicker.d.ts +13 -0
- package/dist/lib/components/pickers/MiniDatePicker.js +42 -0
- package/dist/lib/contacts/contactsApi.d.ts +174 -0
- package/dist/lib/contacts/contactsApi.js +139 -0
- package/dist/lib/contacts/vcard.d.ts +23 -0
- package/dist/lib/contacts/vcard.js +179 -0
- package/dist/lib/crypto/composeSecurity.d.ts +67 -0
- package/dist/lib/crypto/composeSecurity.js +93 -0
- package/dist/lib/crypto/encoding.d.ts +9 -0
- package/dist/lib/crypto/encoding.js +32 -0
- package/dist/lib/crypto/escrowKeys.d.ts +25 -0
- package/dist/lib/crypto/escrowKeys.js +59 -0
- package/dist/lib/crypto/idleTimeout.d.ts +16 -0
- package/dist/lib/crypto/idleTimeout.js +47 -0
- package/dist/lib/crypto/keySession.d.ts +159 -0
- package/dist/lib/crypto/keySession.js +367 -0
- package/dist/lib/crypto/keys.d.ts +50 -0
- package/dist/lib/crypto/keys.js +89 -0
- package/dist/lib/crypto/keyvaultApi.d.ts +394 -0
- package/dist/lib/crypto/keyvaultApi.js +350 -0
- package/dist/lib/crypto/masterKey.d.ts +59 -0
- package/dist/lib/crypto/masterKey.js +104 -0
- package/dist/lib/crypto/masterKeyWraps.d.ts +108 -0
- package/dist/lib/crypto/masterKeyWraps.js +228 -0
- package/dist/lib/crypto/messageSecurity.d.ts +248 -0
- package/dist/lib/crypto/messageSecurity.js +367 -0
- package/dist/lib/crypto/mime.d.ts +143 -0
- package/dist/lib/crypto/mime.js +504 -0
- package/dist/lib/crypto/passkeyUnlock.d.ts +20 -0
- package/dist/lib/crypto/passkeyUnlock.js +79 -0
- package/dist/lib/crypto/passwordUnlock.d.ts +39 -0
- package/dist/lib/crypto/passwordUnlock.js +73 -0
- package/dist/lib/crypto/recoveryCode.d.ts +28 -0
- package/dist/lib/crypto/recoveryCode.js +86 -0
- package/dist/lib/crypto/signingProviderApi.d.ts +95 -0
- package/dist/lib/crypto/signingProviderApi.js +60 -0
- package/dist/lib/crypto/smime.d.ts +128 -0
- package/dist/lib/crypto/smime.js +402 -0
- package/dist/lib/crypto/smimeMessage.d.ts +132 -0
- package/dist/lib/crypto/smimeMessage.js +341 -0
- package/dist/lib/crypto/useIdleKeyTimeout.d.ts +10 -0
- package/dist/lib/crypto/useIdleKeyTimeout.js +163 -0
- package/dist/lib/crypto/verificationSeal.d.ts +56 -0
- package/dist/lib/crypto/verificationSeal.js +220 -0
- package/dist/lib/mail/compose/composeQuoting.d.ts +88 -0
- package/dist/lib/mail/compose/composeQuoting.js +204 -0
- package/dist/lib/mail/compose/emojiData.d.ts +9 -0
- package/dist/lib/mail/compose/emojiData.js +18 -0
- package/dist/lib/mail/compose/giphyApi.d.ts +17 -0
- package/dist/lib/mail/compose/giphyApi.js +20 -0
- package/dist/lib/mail/conversationsApi.d.ts +80 -0
- package/dist/lib/mail/conversationsApi.js +44 -0
- package/dist/lib/mail/dataExportApi.d.ts +50 -0
- package/dist/lib/mail/dataExportApi.js +40 -0
- package/dist/lib/mail/directoryApi.d.ts +49 -0
- package/dist/lib/mail/directoryApi.js +101 -0
- package/dist/lib/mail/erasureRequestApi.d.ts +45 -0
- package/dist/lib/mail/erasureRequestApi.js +43 -0
- package/dist/lib/mail/flaggedMessages.d.ts +22 -0
- package/dist/lib/mail/flaggedMessages.js +73 -0
- package/dist/lib/mail/focusedInboxOverridesApi.d.ts +37 -0
- package/dist/lib/mail/focusedInboxOverridesApi.js +34 -0
- package/dist/lib/mail/labelsApi.d.ts +47 -0
- package/dist/lib/mail/labelsApi.js +38 -0
- package/dist/lib/mail/mailAddress.d.ts +27 -0
- package/dist/lib/mail/mailAddress.js +54 -0
- package/dist/lib/mail/mailApi.d.ts +850 -0
- package/dist/lib/mail/mailApi.js +602 -0
- package/dist/lib/mail/mailDetailHooks.d.ts +10 -0
- package/dist/lib/mail/mailDetailHooks.js +53 -0
- package/dist/lib/mail/mailFilterRulesApi.d.ts +76 -0
- package/dist/lib/mail/mailFilterRulesApi.js +45 -0
- package/dist/lib/mail/mailSignaturesApi.d.ts +49 -0
- package/dist/lib/mail/mailSignaturesApi.js +42 -0
- package/dist/lib/mail/mailboxAccessApi.d.ts +74 -0
- package/dist/lib/mail/mailboxAccessApi.js +56 -0
- package/dist/lib/mail/mailboxImportApi.d.ts +53 -0
- package/dist/lib/mail/mailboxImportApi.js +51 -0
- package/dist/lib/mail/messageBodySanitizer.d.ts +16 -0
- package/dist/lib/mail/messageBodySanitizer.js +118 -0
- package/dist/lib/mail/pushClient.d.ts +106 -0
- package/dist/lib/mail/pushClient.js +317 -0
- package/dist/lib/mail/sendEvents.d.ts +33 -0
- package/dist/lib/mail/sendEvents.js +44 -0
- package/dist/lib/mail/sendFailure.d.ts +16 -0
- package/dist/lib/mail/sendFailure.js +86 -0
- package/dist/lib/mail/senderListsApi.d.ts +69 -0
- package/dist/lib/mail/senderListsApi.js +126 -0
- package/dist/lib/search/queryGrammar.d.ts +51 -0
- package/dist/lib/search/queryGrammar.js +111 -0
- package/dist/lib/search/searchApi.d.ts +100 -0
- package/dist/lib/search/searchApi.js +107 -0
- package/dist/lib/search/searchScoring.d.ts +34 -0
- package/dist/lib/search/searchScoring.js +44 -0
- package/dist/lib/search/searchTier3.d.ts +64 -0
- package/dist/lib/search/searchTier3.js +335 -0
- package/dist/lib/tasks/tasksApi.d.ts +85 -0
- package/dist/lib/tasks/tasksApi.js +55 -0
- package/dist/lib/util/api.d.ts +160 -0
- package/dist/lib/util/api.js +251 -0
- package/dist/lib/util/apiClientContext.d.ts +7 -0
- package/dist/lib/util/apiClientContext.js +32 -0
- package/dist/lib/util/apiQuery.d.ts +32 -0
- package/dist/lib/util/apiQuery.js +42 -0
- package/dist/lib/util/clipboard.d.ts +7 -0
- package/dist/lib/util/clipboard.js +56 -0
- package/dist/lib/util/dateInput.d.ts +6 -0
- package/dist/lib/util/dateInput.js +14 -0
- package/dist/lib/util/timeZone.d.ts +12 -0
- package/dist/lib/util/timeZone.js +32 -0
- package/dist/lib/util/useCopyToClipboard.d.ts +12 -0
- package/dist/lib/util/useCopyToClipboard.js +34 -0
- package/dist/lib/util/useIsMobile.d.ts +10 -0
- package/dist/lib/util/useIsMobile.js +29 -0
- package/dist/lib/videoconf/videoMeetingsApi.d.ts +116 -0
- package/dist/lib/videoconf/videoMeetingsApi.js +49 -0
- package/lib/admin/auditLogApi.ts +48 -0
- package/lib/admin/distributionListsApi.ts +77 -0
- package/lib/admin/domainsApi.ts +113 -0
- package/lib/admin/escrowAccessRequestsApi.ts +110 -0
- package/lib/admin/escrowAuditLogApi.ts +101 -0
- package/lib/admin/escrowScopesApi.ts +112 -0
- package/lib/admin/leftoverMailboxApi.ts +120 -0
- package/lib/admin/mailboxPolicyApi.ts +38 -0
- package/lib/admin/matterExportApi.ts +62 -0
- package/lib/admin/matterSearchApi.ts +35 -0
- package/lib/admin/mattersApi.ts +86 -0
- package/lib/admin/pluginsApi.ts +339 -0
- package/lib/admin/retentionPolicyApi.ts +46 -0
- package/lib/admin/setupApi.ts +40 -0
- package/lib/admin/transportRulesApi.ts +106 -0
- package/lib/appearance/preferencesApi.ts +335 -0
- package/lib/auth/profileApi.ts +77 -0
- package/lib/auth/session.ts +238 -0
- package/lib/branding/brandingApi.ts +97 -0
- package/lib/branding/useBranding.ts +81 -0
- package/lib/calendar/calendarApi.ts +309 -0
- package/lib/calendar/calendarColors.ts +45 -0
- package/lib/calendar/calendarDragIds.ts +112 -0
- package/lib/calendar/calendarMutations.ts +236 -0
- package/lib/calendar/eventDescription.ts +211 -0
- package/lib/calendar/freeBusyApi.ts +197 -0
- package/lib/calendar/inviteApi.ts +154 -0
- package/lib/calendar/recurrence.ts +285 -0
- package/lib/components/avatar/ContactAvatar.tsx +47 -0
- package/lib/components/buttons/Button.tsx +40 -0
- package/lib/components/buttons/CopyButton.tsx +45 -0
- package/lib/components/feedback/Alert.tsx +13 -0
- package/lib/components/feedback/Skeleton.tsx +38 -0
- package/lib/components/forms/FormField.tsx +23 -0
- package/lib/components/navigation/BottomTabBar.tsx +66 -0
- package/lib/components/overlays/Drawer.tsx +72 -0
- package/lib/components/overlays/Modal.tsx +64 -0
- package/lib/components/overlays/PopoverPortal.tsx +74 -0
- package/lib/components/overlays/overlayStack.ts +165 -0
- package/lib/components/pickers/MiniDatePicker.tsx +90 -0
- package/lib/contacts/contactsApi.ts +289 -0
- package/lib/contacts/vcard.ts +197 -0
- package/lib/crypto/composeSecurity.ts +140 -0
- package/lib/crypto/encoding.ts +36 -0
- package/lib/crypto/escrowKeys.ts +74 -0
- package/lib/crypto/idleTimeout.ts +49 -0
- package/lib/crypto/keySession.ts +483 -0
- package/lib/crypto/keys.ts +105 -0
- package/lib/crypto/keyvaultApi.ts +674 -0
- package/lib/crypto/masterKey.ts +134 -0
- package/lib/crypto/masterKeyWraps.ts +269 -0
- package/lib/crypto/messageSecurity.ts +600 -0
- package/lib/crypto/mime.ts +568 -0
- package/lib/crypto/passkeyUnlock.ts +103 -0
- package/lib/crypto/passwordUnlock.ts +98 -0
- package/lib/crypto/recoveryCode.ts +93 -0
- package/lib/crypto/signingProviderApi.ts +135 -0
- package/lib/crypto/smime.ts +459 -0
- package/lib/crypto/smimeMessage.ts +491 -0
- package/lib/crypto/useIdleKeyTimeout.ts +176 -0
- package/lib/crypto/verificationSeal.ts +288 -0
- package/lib/mail/compose/composeQuoting.ts +243 -0
- package/lib/mail/compose/emojiData.ts +34 -0
- package/lib/mail/compose/giphyApi.ts +31 -0
- package/lib/mail/conversationsApi.ts +123 -0
- package/lib/mail/dataExportApi.ts +73 -0
- package/lib/mail/directoryApi.ts +161 -0
- package/lib/mail/erasureRequestApi.ts +71 -0
- package/lib/mail/flaggedMessages.ts +80 -0
- package/lib/mail/focusedInboxOverridesApi.ts +64 -0
- package/lib/mail/labelsApi.ts +71 -0
- package/lib/mail/mailAddress.ts +76 -0
- package/lib/mail/mailApi.ts +1286 -0
- package/lib/mail/mailDetailHooks.ts +57 -0
- package/lib/mail/mailFilterRulesApi.ts +116 -0
- package/lib/mail/mailSignaturesApi.ts +84 -0
- package/lib/mail/mailboxAccessApi.ts +106 -0
- package/lib/mail/mailboxImportApi.ts +87 -0
- package/lib/mail/messageBodySanitizer.ts +129 -0
- package/lib/mail/pushClient.ts +375 -0
- package/lib/mail/sendEvents.ts +72 -0
- package/lib/mail/sendFailure.ts +98 -0
- package/lib/mail/senderListsApi.ts +161 -0
- package/lib/search/queryGrammar.ts +179 -0
- package/lib/search/searchApi.ts +199 -0
- package/lib/search/searchScoring.ts +46 -0
- package/lib/search/searchTier3.ts +406 -0
- package/lib/tasks/tasksApi.ts +128 -0
- package/lib/util/api.ts +318 -0
- package/lib/util/apiClientContext.ts +35 -0
- package/lib/util/apiQuery.ts +61 -0
- package/lib/util/clipboard.ts +55 -0
- package/lib/util/dateInput.ts +15 -0
- package/lib/util/timeZone.ts +33 -0
- package/lib/util/useCopyToClipboard.ts +48 -0
- package/lib/util/useIsMobile.ts +34 -0
- package/lib/videoconf/videoMeetingsApi.ts +144 -0
- 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;
|