@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,195 @@
|
|
|
1
|
+
///////////////////////////////////////////////////////////////////////////////
|
|
2
|
+
// Copyright (C) 2026 Jean-Philippe Steinmetz
|
|
3
|
+
// SPDX-License-Identifier: MPL-2.0
|
|
4
|
+
///////////////////////////////////////////////////////////////////////////////
|
|
5
|
+
/**
|
|
6
|
+
* 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
|
|
7
|
+
* (`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
|
|
8
|
+
* 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
|
|
9
|
+
* 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
|
|
10
|
+
* everything a client shows or sends is made from that tree: `renderable` by React elements (no `dangerouslySetInnerHTML`), written back out as canonical
|
|
11
|
+
* HTML (`sanitizeEventDescriptionHtml()`) or as plain text (`htmlToPlainText()`, the same text the server derives).
|
|
12
|
+
*
|
|
13
|
+
* Reading needs a DOM (`DOMParser`); without one (server-side rendering) the tree is empty, never the input.
|
|
14
|
+
*/
|
|
15
|
+
/** The longest plain-text description the server takes, in characters (it allows a little more; this is the bound the dialog holds itself to). */
|
|
16
|
+
export const MAX_EVENT_DESCRIPTION_LENGTH = 32000;
|
|
17
|
+
/** The longest description HTML the server takes, in characters. */
|
|
18
|
+
export const MAX_EVENT_DESCRIPTION_HTML_LENGTH = 64000;
|
|
19
|
+
const TAG_OF = {
|
|
20
|
+
b: "strong",
|
|
21
|
+
strong: "strong",
|
|
22
|
+
i: "em",
|
|
23
|
+
em: "em",
|
|
24
|
+
u: "u",
|
|
25
|
+
br: "br",
|
|
26
|
+
p: "p",
|
|
27
|
+
ul: "ul",
|
|
28
|
+
ol: "ol",
|
|
29
|
+
li: "li",
|
|
30
|
+
a: "a",
|
|
31
|
+
};
|
|
32
|
+
/** Elements that run or embed something: dropped with everything in them (any other element outside the list keeps its text but not its tags). */
|
|
33
|
+
const DROPPED = new Set(["script", "style", "iframe", "frame", "frameset", "object", "embed", "applet", "svg", "math", "template", "noscript", "noembed", "noframes", "textarea", "select", "option", "title", "head", "xmp"]);
|
|
34
|
+
/**
|
|
35
|
+
* `href` as a link a description may carry - an absolute `http`, `https` or `mailto` URL, in its canonical form - or `undefined` for anything else
|
|
36
|
+
* (`javascript:`, `data:`, a relative link, a URL with a control character in it). Whitespace and control characters are removed first, since a browser
|
|
37
|
+
* ignores them inside a scheme (`java\tscript:`).
|
|
38
|
+
*/
|
|
39
|
+
export function safeDescriptionHref(href) {
|
|
40
|
+
const compact = (href ?? "").replace(/[\p{Cc}\s]+/gu, "");
|
|
41
|
+
let url;
|
|
42
|
+
try {
|
|
43
|
+
url = new URL(compact);
|
|
44
|
+
}
|
|
45
|
+
catch {
|
|
46
|
+
return undefined;
|
|
47
|
+
}
|
|
48
|
+
return ["http:", "https:", "mailto:"].includes(url.protocol) ? url.href : undefined;
|
|
49
|
+
}
|
|
50
|
+
function convert(node) {
|
|
51
|
+
if (node.nodeType === 3) {
|
|
52
|
+
return [{ text: node.textContent }];
|
|
53
|
+
}
|
|
54
|
+
if (node.nodeType !== 1) {
|
|
55
|
+
return [];
|
|
56
|
+
}
|
|
57
|
+
const element = node;
|
|
58
|
+
const name = element.tagName.toLowerCase();
|
|
59
|
+
if (DROPPED.has(name)) {
|
|
60
|
+
return [];
|
|
61
|
+
}
|
|
62
|
+
const tag = TAG_OF[name];
|
|
63
|
+
if (tag === "br") {
|
|
64
|
+
return [{ tag, children: [] }];
|
|
65
|
+
}
|
|
66
|
+
const children = Array.from(element.childNodes).flatMap(convert);
|
|
67
|
+
if (!tag) {
|
|
68
|
+
return children;
|
|
69
|
+
}
|
|
70
|
+
if (tag === "a") {
|
|
71
|
+
const href = safeDescriptionHref(element.getAttribute("href"));
|
|
72
|
+
return href ? [{ tag, href, children }] : children;
|
|
73
|
+
}
|
|
74
|
+
if (tag === "p" && element.parentElement?.tagName.toLowerCase() === "li") {
|
|
75
|
+
// A list item written `<li><p>text</p></li>` (what a rich-text editor writes) is `<li>text</li>`: a paragraph inside an item would otherwise
|
|
76
|
+
// break the line after its bullet. A second paragraph in the same item stays on its own line.
|
|
77
|
+
return element.previousElementSibling ? [{ tag: "br", children: [] }, ...children] : children;
|
|
78
|
+
}
|
|
79
|
+
return [{ tag, children }];
|
|
80
|
+
}
|
|
81
|
+
/** The elements and text of `html` a description may hold, and nothing else. `[]` without a DOM. */
|
|
82
|
+
export function parseEventDescription(html) {
|
|
83
|
+
if (!html || typeof DOMParser === "undefined") {
|
|
84
|
+
return [];
|
|
85
|
+
}
|
|
86
|
+
const document = new DOMParser().parseFromString(html, "text/html");
|
|
87
|
+
return Array.from(document.body.childNodes).flatMap(convert);
|
|
88
|
+
}
|
|
89
|
+
function escapeText(text) {
|
|
90
|
+
return text.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
|
91
|
+
}
|
|
92
|
+
function escapeAttribute(text) {
|
|
93
|
+
return escapeText(text).replace(/"/g, """);
|
|
94
|
+
}
|
|
95
|
+
function serialize(nodes) {
|
|
96
|
+
return nodes
|
|
97
|
+
.map((node) => {
|
|
98
|
+
if ("text" in node) {
|
|
99
|
+
return escapeText(node.text);
|
|
100
|
+
}
|
|
101
|
+
if (node.tag === "br") {
|
|
102
|
+
return "<br>";
|
|
103
|
+
}
|
|
104
|
+
const open = node.tag === "a" ? `<a href="${escapeAttribute(node.href)}" rel="noopener noreferrer">` : `<${node.tag}>`;
|
|
105
|
+
return `${open}${serialize(node.children)}</${node.tag}>`;
|
|
106
|
+
})
|
|
107
|
+
.join("");
|
|
108
|
+
}
|
|
109
|
+
/** Nothing but white space: text of spaces, a line break, or a paragraph or line break holding only such (what an editor writes for an empty line). */
|
|
110
|
+
function isBlank(node) {
|
|
111
|
+
return "text" in node ? node.text.trim() === "" : (node.tag === "p" || node.tag === "br") && node.children.every(isBlank);
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* `html` reduced to what a description may hold, written as canonical HTML (a link with `rel="noopener noreferrer"`, text and attribute values escaped,
|
|
115
|
+
* 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.
|
|
116
|
+
* This is what the dialog sends; the server sanitizes it again. `""` without a DOM.
|
|
117
|
+
*/
|
|
118
|
+
export function sanitizeEventDescriptionHtml(html) {
|
|
119
|
+
const nodes = parseEventDescription(html);
|
|
120
|
+
let first = 0;
|
|
121
|
+
let last = nodes.length;
|
|
122
|
+
while (first < last && isBlank(nodes[first])) {
|
|
123
|
+
first++;
|
|
124
|
+
}
|
|
125
|
+
while (last > first && isBlank(nodes[last - 1])) {
|
|
126
|
+
last--;
|
|
127
|
+
}
|
|
128
|
+
return serialize(nodes.slice(first, last));
|
|
129
|
+
}
|
|
130
|
+
function startLine(state) {
|
|
131
|
+
if (state.text !== "" && !state.text.endsWith("\n")) {
|
|
132
|
+
state.text += "\n";
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
function writeText(nodes, state) {
|
|
136
|
+
for (const node of nodes) {
|
|
137
|
+
if ("text" in node) {
|
|
138
|
+
const collapsed = node.text.replace(/(?![\t\n\r])\p{Cc}/gu, "").replace(/[ \t\r\n]+/g, " ");
|
|
139
|
+
state.text += state.text === "" || state.text.endsWith("\n") ? collapsed.replace(/^ /, "") : collapsed;
|
|
140
|
+
}
|
|
141
|
+
else if (node.tag === "br") {
|
|
142
|
+
state.text += "\n";
|
|
143
|
+
}
|
|
144
|
+
else if (node.tag === "p") {
|
|
145
|
+
startLine(state);
|
|
146
|
+
writeText(node.children, state);
|
|
147
|
+
startLine(state);
|
|
148
|
+
}
|
|
149
|
+
else if (node.tag === "ul" || node.tag === "ol") {
|
|
150
|
+
startLine(state);
|
|
151
|
+
state.lists.push({ ordered: node.tag === "ol", count: 0 });
|
|
152
|
+
writeText(node.children, state);
|
|
153
|
+
state.lists.pop();
|
|
154
|
+
startLine(state);
|
|
155
|
+
}
|
|
156
|
+
else if (node.tag === "li") {
|
|
157
|
+
startLine(state);
|
|
158
|
+
const list = state.lists[state.lists.length - 1];
|
|
159
|
+
if (list?.ordered) {
|
|
160
|
+
list.count++;
|
|
161
|
+
state.text += `${list.count}. `;
|
|
162
|
+
}
|
|
163
|
+
else {
|
|
164
|
+
state.text += "- ";
|
|
165
|
+
}
|
|
166
|
+
writeText(node.children, state);
|
|
167
|
+
startLine(state);
|
|
168
|
+
}
|
|
169
|
+
else if (node.tag === "a") {
|
|
170
|
+
const start = state.text.length;
|
|
171
|
+
writeText(node.children, state);
|
|
172
|
+
const shown = state.text.slice(start).trim();
|
|
173
|
+
const href = node.href;
|
|
174
|
+
if (shown !== href && shown !== href.replace(/^mailto:/i, "")) {
|
|
175
|
+
state.text += ` (${href})`;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
else {
|
|
179
|
+
writeText(node.children, state);
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* 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
|
|
185
|
+
* 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
|
|
186
|
+
* blank lines shortened. `""` for a description with no text in it, and without a DOM.
|
|
187
|
+
*/
|
|
188
|
+
export function htmlToPlainText(html) {
|
|
189
|
+
const state = { text: "", lists: [] };
|
|
190
|
+
writeText(parseEventDescription(html), state);
|
|
191
|
+
return state.text
|
|
192
|
+
.replace(/[ \t]+\n/g, "\n")
|
|
193
|
+
.replace(/\n{3,}/g, "\n\n")
|
|
194
|
+
.trim();
|
|
195
|
+
}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
/** The client of `@rapidmx/restapi`'s `POST /mail/calendar-events/free-busy` - when other people are busy, for an event dialog's "Find a time" - and the
|
|
2
|
+
* small pure helpers that turn its answer into what a grid and a list of suggested times need.
|
|
3
|
+
*
|
|
4
|
+
* What the server tells about a person is only ever when they are busy, never why: no title, place, guest or id. And for some people it tells nothing at
|
|
5
|
+
* all, which is not the same as telling they are free: `"unknown"` is a person the server has no calendar for (an external address, or a calendar too big
|
|
6
|
+
* to read) and `"restricted"` is one who chose not to share their free/busy with the caller (`Mailbox.freeBusyVisibility`). Every helper here treats both
|
|
7
|
+
* as *not known to be free* - they are never counted as available, and never make a time "free for everyone". */
|
|
8
|
+
import { ApiClient } from "../util/api.js";
|
|
9
|
+
/** The most addresses one request may ask about. */
|
|
10
|
+
export declare const FREE_BUSY_MAX_ADDRESSES = 50;
|
|
11
|
+
/** The longest window one request may ask about, in days. */
|
|
12
|
+
export declare const FREE_BUSY_MAX_DAYS = 31;
|
|
13
|
+
/** `"available"`: the server read the person's calendar (`busy` is what it found). `"unknown"`: it has no information. `"restricted"`: they hide it from you. */
|
|
14
|
+
export type FreeBusyStatus = "available" | "unknown" | "restricted";
|
|
15
|
+
/** One stretch of busy time, as the server sends it (UTC ISO 8601, sorted, merged and clipped to the window). */
|
|
16
|
+
export interface FreeBusyWindow {
|
|
17
|
+
start: string;
|
|
18
|
+
end: string;
|
|
19
|
+
/** Only tentatively busy (a tentative event, or an invitation not yet answered firmly). */
|
|
20
|
+
tentative: boolean;
|
|
21
|
+
}
|
|
22
|
+
export interface FreeBusyResult {
|
|
23
|
+
address: string;
|
|
24
|
+
status: FreeBusyStatus;
|
|
25
|
+
/** Empty unless `status` is `"available"`. */
|
|
26
|
+
busy: FreeBusyWindow[];
|
|
27
|
+
}
|
|
28
|
+
export interface FreeBusyResponse {
|
|
29
|
+
start: string;
|
|
30
|
+
end: string;
|
|
31
|
+
/** One result per address asked, in the order asked. */
|
|
32
|
+
results: FreeBusyResult[];
|
|
33
|
+
}
|
|
34
|
+
/** `client`, given by every function below, is an explicit `ApiClient` from `createApiClient()` (e.g. one
|
|
35
|
+
* account of a multi-account app) to call instead of the default global `apiFetch()` - see `withClient()`'s
|
|
36
|
+
* own doc comment in `util/api.ts`. Omitted (the default), every function here behaves exactly as before. */
|
|
37
|
+
/**
|
|
38
|
+
* When the people at `addresses` (1 to `FREE_BUSY_MAX_ADDRESSES`) are busy between `start` and `end` (at most `FREE_BUSY_MAX_DAYS` days). The caller's own
|
|
39
|
+
* mailboxes are always answered as available with their real busy time. Rejects with an `ApiRequestError`: 400 for a bad request, 401 when signed out,
|
|
40
|
+
* 429 when asked too often (60 a minute).
|
|
41
|
+
*/
|
|
42
|
+
export declare function getFreeBusy(addresses: string[], start: Date | string, end: Date | string, client?: ApiClient): Promise<FreeBusyResponse>;
|
|
43
|
+
/** A stretch of busy time as milliseconds since the epoch. */
|
|
44
|
+
export interface BusyBlock {
|
|
45
|
+
startMs: number;
|
|
46
|
+
endMs: number;
|
|
47
|
+
tentative: boolean;
|
|
48
|
+
}
|
|
49
|
+
/** What is known about one person's time. */
|
|
50
|
+
export interface PersonAvailability {
|
|
51
|
+
address: string;
|
|
52
|
+
status: FreeBusyStatus;
|
|
53
|
+
busy: BusyBlock[];
|
|
54
|
+
}
|
|
55
|
+
/** What a person's calendar says about a stretch of time. `"unknown"` is any person the server did not (or would not) tell about - never free. */
|
|
56
|
+
export type AvailabilityState = "free" | "tentative" | "busy" | "unknown";
|
|
57
|
+
/** The response's results with their times as milliseconds (a person who isn't `"available"` has no blocks whatever the server sent). */
|
|
58
|
+
export declare function availabilityOf(response: FreeBusyResponse): PersonAvailability[];
|
|
59
|
+
/** What `person` is between `startMs` and `endMs`: `"busy"` when a firm block overlaps, else `"tentative"` when a tentative one does, else `"free"` - and
|
|
60
|
+
* `"unknown"`, whatever the blocks, for a person who isn't `"available"`. */
|
|
61
|
+
export declare function availabilityDuring(person: PersonAvailability, startMs: number, endMs: number): AvailabilityState;
|
|
62
|
+
/** How a stretch of time stands for a group. */
|
|
63
|
+
export interface AvailabilitySummary {
|
|
64
|
+
/** People known to be busy for some of it (firm or tentative). */
|
|
65
|
+
conflicts: number;
|
|
66
|
+
/** Of those, the ones only tentatively busy. */
|
|
67
|
+
tentative: number;
|
|
68
|
+
/** People nothing is known about (external, too big, or hiding their calendar): not counted as free, not counted as conflicts. */
|
|
69
|
+
unknown: number;
|
|
70
|
+
/** People known to be free for all of it. */
|
|
71
|
+
free: number;
|
|
72
|
+
}
|
|
73
|
+
export declare function summarizeAvailability(people: PersonAvailability[], startMs: number, endMs: number): AvailabilitySummary;
|
|
74
|
+
/**
|
|
75
|
+
* `people` without the blocks that are exactly the stretch from `startMs` to `endMs`, for the addresses in `addresses` (lower case): what an event that is
|
|
76
|
+
* being rescheduled takes up on the calendars of the people already invited to it - which would otherwise show as everyone's conflict with itself. Only an
|
|
77
|
+
* exact match goes, so a block that the server merged with a neighbouring or overlapping event stays (a conflict shown, never one hidden).
|
|
78
|
+
*/
|
|
79
|
+
export declare function withoutOwnBlock(people: PersonAvailability[], addresses: Set<string>, startMs: number, endMs: number): PersonAvailability[];
|
|
80
|
+
export interface SuggestTimesOptions {
|
|
81
|
+
/** The stretches a meeting may fall in (e.g. each day's 8:00 to 18:00), in any order. A slot lies wholly inside one. */
|
|
82
|
+
windows: {
|
|
83
|
+
startMs: number;
|
|
84
|
+
endMs: number;
|
|
85
|
+
}[];
|
|
86
|
+
/** How long the meeting is. */
|
|
87
|
+
durationMs: number;
|
|
88
|
+
/** How far apart slots start, from a window's start (default 30 minutes). */
|
|
89
|
+
stepMs?: number;
|
|
90
|
+
/** How many to find (default 5). */
|
|
91
|
+
limit?: number;
|
|
92
|
+
/** No slot starts before this (e.g. now). */
|
|
93
|
+
notBeforeMs?: number;
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* The start times (ms) of the first `limit` slots of `durationMs` inside `windows` where everyone known is free - no firm or tentative block overlaps it.
|
|
97
|
+
* People who are `"unknown"` or `"restricted"` cannot be checked and so do not constrain the answer (a caller says so next to the suggestions); with nobody
|
|
98
|
+
* known at all there is nothing to base a suggestion on and the answer is empty.
|
|
99
|
+
*/
|
|
100
|
+
export declare function suggestTimes(people: PersonAvailability[], options: SuggestTimesOptions): number[];
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
///////////////////////////////////////////////////////////////////////////////
|
|
2
|
+
// Copyright (C) 2026 Jean-Philippe Steinmetz
|
|
3
|
+
// SPDX-License-Identifier: MPL-2.0
|
|
4
|
+
///////////////////////////////////////////////////////////////////////////////
|
|
5
|
+
/** The client of `@rapidmx/restapi`'s `POST /mail/calendar-events/free-busy` - when other people are busy, for an event dialog's "Find a time" - and the
|
|
6
|
+
* small pure helpers that turn its answer into what a grid and a list of suggested times need.
|
|
7
|
+
*
|
|
8
|
+
* What the server tells about a person is only ever when they are busy, never why: no title, place, guest or id. And for some people it tells nothing at
|
|
9
|
+
* all, which is not the same as telling they are free: `"unknown"` is a person the server has no calendar for (an external address, or a calendar too big
|
|
10
|
+
* to read) and `"restricted"` is one who chose not to share their free/busy with the caller (`Mailbox.freeBusyVisibility`). Every helper here treats both
|
|
11
|
+
* as *not known to be free* - they are never counted as available, and never make a time "free for everyone". */
|
|
12
|
+
import { withClient } from "../util/api.js";
|
|
13
|
+
/** The most addresses one request may ask about. */
|
|
14
|
+
export const FREE_BUSY_MAX_ADDRESSES = 50;
|
|
15
|
+
/** The longest window one request may ask about, in days. */
|
|
16
|
+
export const FREE_BUSY_MAX_DAYS = 31;
|
|
17
|
+
/** `client`, given by every function below, is an explicit `ApiClient` from `createApiClient()` (e.g. one
|
|
18
|
+
* account of a multi-account app) to call instead of the default global `apiFetch()` - see `withClient()`'s
|
|
19
|
+
* own doc comment in `util/api.ts`. Omitted (the default), every function here behaves exactly as before. */
|
|
20
|
+
/**
|
|
21
|
+
* When the people at `addresses` (1 to `FREE_BUSY_MAX_ADDRESSES`) are busy between `start` and `end` (at most `FREE_BUSY_MAX_DAYS` days). The caller's own
|
|
22
|
+
* mailboxes are always answered as available with their real busy time. Rejects with an `ApiRequestError`: 400 for a bad request, 401 when signed out,
|
|
23
|
+
* 429 when asked too often (60 a minute).
|
|
24
|
+
*/
|
|
25
|
+
export function getFreeBusy(addresses, start, end, client) {
|
|
26
|
+
return withClient(client, "/mail/calendar-events/free-busy", {
|
|
27
|
+
method: "POST",
|
|
28
|
+
body: JSON.stringify({
|
|
29
|
+
addresses,
|
|
30
|
+
start: typeof start === "string" ? start : start.toISOString(),
|
|
31
|
+
end: typeof end === "string" ? end : end.toISOString(),
|
|
32
|
+
}),
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
/** The response's results with their times as milliseconds (a person who isn't `"available"` has no blocks whatever the server sent). */
|
|
36
|
+
export function availabilityOf(response) {
|
|
37
|
+
return response.results.map((result) => ({
|
|
38
|
+
address: result.address,
|
|
39
|
+
status: result.status,
|
|
40
|
+
busy: result.status === "available"
|
|
41
|
+
? result.busy.map((window) => ({ startMs: Date.parse(window.start), endMs: Date.parse(window.end), tentative: window.tentative }))
|
|
42
|
+
: [],
|
|
43
|
+
}));
|
|
44
|
+
}
|
|
45
|
+
/** Whether a block overlaps the stretch from `startMs` to `endMs` (touching ends do not overlap). */
|
|
46
|
+
function overlaps(block, startMs, endMs) {
|
|
47
|
+
return block.startMs < endMs && block.endMs > startMs;
|
|
48
|
+
}
|
|
49
|
+
/** What `person` is between `startMs` and `endMs`: `"busy"` when a firm block overlaps, else `"tentative"` when a tentative one does, else `"free"` - and
|
|
50
|
+
* `"unknown"`, whatever the blocks, for a person who isn't `"available"`. */
|
|
51
|
+
export function availabilityDuring(person, startMs, endMs) {
|
|
52
|
+
if (person.status !== "available") {
|
|
53
|
+
return "unknown";
|
|
54
|
+
}
|
|
55
|
+
const overlapping = person.busy.filter((block) => overlaps(block, startMs, endMs));
|
|
56
|
+
if (overlapping.some((block) => !block.tentative)) {
|
|
57
|
+
return "busy";
|
|
58
|
+
}
|
|
59
|
+
return overlapping.length > 0 ? "tentative" : "free";
|
|
60
|
+
}
|
|
61
|
+
export function summarizeAvailability(people, startMs, endMs) {
|
|
62
|
+
const summary = { conflicts: 0, tentative: 0, unknown: 0, free: 0 };
|
|
63
|
+
for (const person of people) {
|
|
64
|
+
const state = availabilityDuring(person, startMs, endMs);
|
|
65
|
+
if (state === "unknown") {
|
|
66
|
+
summary.unknown++;
|
|
67
|
+
}
|
|
68
|
+
else if (state === "free") {
|
|
69
|
+
summary.free++;
|
|
70
|
+
}
|
|
71
|
+
else {
|
|
72
|
+
summary.conflicts++;
|
|
73
|
+
if (state === "tentative") {
|
|
74
|
+
summary.tentative++;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
return summary;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* `people` without the blocks that are exactly the stretch from `startMs` to `endMs`, for the addresses in `addresses` (lower case): what an event that is
|
|
82
|
+
* being rescheduled takes up on the calendars of the people already invited to it - which would otherwise show as everyone's conflict with itself. Only an
|
|
83
|
+
* exact match goes, so a block that the server merged with a neighbouring or overlapping event stays (a conflict shown, never one hidden).
|
|
84
|
+
*/
|
|
85
|
+
export function withoutOwnBlock(people, addresses, startMs, endMs) {
|
|
86
|
+
return people.map((person) => addresses.has(person.address.toLowerCase())
|
|
87
|
+
? { ...person, busy: person.busy.filter((block) => block.startMs !== startMs || block.endMs !== endMs) }
|
|
88
|
+
: person);
|
|
89
|
+
}
|
|
90
|
+
const DEFAULT_STEP_MS = 30 * 60000;
|
|
91
|
+
const DEFAULT_SUGGESTIONS = 5;
|
|
92
|
+
/**
|
|
93
|
+
* The start times (ms) of the first `limit` slots of `durationMs` inside `windows` where everyone known is free - no firm or tentative block overlaps it.
|
|
94
|
+
* People who are `"unknown"` or `"restricted"` cannot be checked and so do not constrain the answer (a caller says so next to the suggestions); with nobody
|
|
95
|
+
* known at all there is nothing to base a suggestion on and the answer is empty.
|
|
96
|
+
*/
|
|
97
|
+
export function suggestTimes(people, options) {
|
|
98
|
+
const known = people.filter((person) => person.status === "available");
|
|
99
|
+
if (known.length === 0 || options.durationMs <= 0) {
|
|
100
|
+
return [];
|
|
101
|
+
}
|
|
102
|
+
const step = options.stepMs ?? DEFAULT_STEP_MS;
|
|
103
|
+
const limit = options.limit ?? DEFAULT_SUGGESTIONS;
|
|
104
|
+
const found = [];
|
|
105
|
+
for (const window of [...options.windows].sort((a, b) => a.startMs - b.startMs)) {
|
|
106
|
+
for (let start = window.startMs; start + options.durationMs <= window.endMs; start += step) {
|
|
107
|
+
if (start < (options.notBeforeMs ?? Number.NEGATIVE_INFINITY)) {
|
|
108
|
+
continue;
|
|
109
|
+
}
|
|
110
|
+
if (known.every((person) => availabilityDuring(person, start, start + options.durationMs) === "free")) {
|
|
111
|
+
found.push(start);
|
|
112
|
+
if (found.length >= limit) {
|
|
113
|
+
return found;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
return found;
|
|
119
|
+
}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
/** Typed wrappers over `@rapidmx/restapi`'s `/mail/calendar-events/invite` surface - the calendar invitation (iMIP: an
|
|
2
|
+
* `.ics` attachment carrying an iTIP `METHOD`) a mail message may hold, read for the reading pane's invitation card. The
|
|
3
|
+
* server does all the work of an answer: it puts the meeting on the reader's calendar (or takes it off), and sends the
|
|
4
|
+
* iTIP REPLY to the organizer. The client only reads the state and asks for a change; every call returns the invitation as
|
|
5
|
+
* it now stands, ready to draw. */
|
|
6
|
+
import { ApiClient } from "../util/api.js";
|
|
7
|
+
import type { EventVisibility, GuestPermissions } from "./calendarApi.js";
|
|
8
|
+
/** What the reader can answer an invitation with. */
|
|
9
|
+
export type InviteResponse = "accepted" | "tentative" | "declined";
|
|
10
|
+
export interface InviteParticipant {
|
|
11
|
+
address: string;
|
|
12
|
+
displayName?: string;
|
|
13
|
+
responseStatus?: "accepted" | "tentative" | "declined" | "needs-action";
|
|
14
|
+
}
|
|
15
|
+
/** One of the reader's own events near an invitation, as the server lists it for the RSVP day view and its conflict check. */
|
|
16
|
+
export interface InviteScheduleEntry {
|
|
17
|
+
uid: string;
|
|
18
|
+
title: string;
|
|
19
|
+
/** ISO 8601 instants. */
|
|
20
|
+
startDate: string;
|
|
21
|
+
endDate: string;
|
|
22
|
+
allDay: boolean;
|
|
23
|
+
/** The event blocks the reader's time (it is not marked free). */
|
|
24
|
+
busy: boolean;
|
|
25
|
+
tentative: boolean;
|
|
26
|
+
}
|
|
27
|
+
/** The calendar invitation a message carries, together with what the reader's own calendar says about it. */
|
|
28
|
+
export interface MessageInvite {
|
|
29
|
+
/** The iTIP `METHOD` as sent: `"REQUEST"`, `"CANCEL"`, `"REPLY"`, `"PUBLISH"` or `"COUNTER"`, or `""` when the file names none. */
|
|
30
|
+
method: string;
|
|
31
|
+
/** The iCalendar `UID`. */
|
|
32
|
+
uid: string;
|
|
33
|
+
sequence: number;
|
|
34
|
+
summary?: string;
|
|
35
|
+
location?: string;
|
|
36
|
+
/** ISO 8601 instant. */
|
|
37
|
+
startDate?: string;
|
|
38
|
+
endDate?: string;
|
|
39
|
+
allDay: boolean;
|
|
40
|
+
/** The IANA zone the organizer used. */
|
|
41
|
+
timezone?: string;
|
|
42
|
+
organizer?: {
|
|
43
|
+
address: string;
|
|
44
|
+
displayName?: string;
|
|
45
|
+
};
|
|
46
|
+
attendees: InviteParticipant[];
|
|
47
|
+
recurring: boolean;
|
|
48
|
+
/** The reader's mailbox is the organizer. */
|
|
49
|
+
isOrganizer: boolean;
|
|
50
|
+
/** What the reader answered, if anything. */
|
|
51
|
+
response?: InviteResponse;
|
|
52
|
+
/** An event for it is on the reader's calendar now. */
|
|
53
|
+
onCalendar: boolean;
|
|
54
|
+
/** That event's uid (for a link into the calendar). */
|
|
55
|
+
calendarEventUid?: string;
|
|
56
|
+
/** The calendar already holds a newer revision than this message. */
|
|
57
|
+
outdated: boolean;
|
|
58
|
+
/** A `REQUEST` addressed to the reader: offer Accept / Tentative / Decline. */
|
|
59
|
+
canRespond: boolean;
|
|
60
|
+
/** A `PUBLISH`, or no method at all: offer "Add to calendar". */
|
|
61
|
+
canAdd: boolean;
|
|
62
|
+
/** A `CANCEL` whose meeting is on the calendar: offer "Remove from calendar". */
|
|
63
|
+
canRemove: boolean;
|
|
64
|
+
/** A `REQUEST` the reader can answer with a different time: offer "Propose new time". */
|
|
65
|
+
canPropose: boolean;
|
|
66
|
+
/** A `COUNTER` for a meeting the reader organizes: offer "Accept proposal". */
|
|
67
|
+
canAcceptProposal: boolean;
|
|
68
|
+
/** For a `REPLY` or `COUNTER`: the attendee who sent it and what they answered or proposed. For a `COUNTER`,
|
|
69
|
+
* `startDate`/`endDate` are the proposed time. */
|
|
70
|
+
reply?: InviteParticipant;
|
|
71
|
+
/** The reader's busy events that overlap the invitation's time. */
|
|
72
|
+
conflicts: InviteScheduleEntry[];
|
|
73
|
+
/** The reader's other events from 12 hours before the invitation's start to 12 hours after its end (recurrences
|
|
74
|
+
* expanded, this meeting left out) - what the RSVP day view draws around the invitation. */
|
|
75
|
+
schedule: InviteScheduleEntry[];
|
|
76
|
+
/** The description as plain text, if the organizer wrote one. */
|
|
77
|
+
description?: string;
|
|
78
|
+
/** The description as HTML the server sanitized - still rendered through `sanitizeEventDescriptionHtml()`, never trusted as it stands. */
|
|
79
|
+
descriptionHtml?: string;
|
|
80
|
+
/** Who may see the event's details, as the organizer sent it. */
|
|
81
|
+
visibility?: EventVisibility;
|
|
82
|
+
/** What the organizer allows the guests to do. Every field is present when the server says any (all optional here so an older server, which says none, reads
|
|
83
|
+
* as the defaults - see `guestPermissionsOf()`). */
|
|
84
|
+
guestPermissions?: Partial<GuestPermissions>;
|
|
85
|
+
/** A guest's copy that allows a change of the title, location, description or time: offer "Request a change" (`requestEventChange()` on `calendarEventUid`). */
|
|
86
|
+
canRequestChange?: boolean;
|
|
87
|
+
/** A guest's copy that allows adding guests: offer "Add guests" (`requestEventChange()` with `addAttendees` on `calendarEventUid`). */
|
|
88
|
+
canRequestInvite?: boolean;
|
|
89
|
+
/** On a `COUNTER` that is a guest's change request (rather than a proposed time) received by the organizer: whether it was applied automatically. */
|
|
90
|
+
changeRequest?: {
|
|
91
|
+
applied: boolean;
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
/** `client`, given by every function below, is an explicit `ApiClient` from `createApiClient()` (e.g. one
|
|
95
|
+
* account of a multi-account app) to call instead of the default global `apiFetch()` - see `withClient()`'s
|
|
96
|
+
* own doc comment in `util/api.ts`. Omitted (the default), every function here behaves exactly as before. */
|
|
97
|
+
/**
|
|
98
|
+
* Reads the invitation a message carries. Resolves `null` when the message has none the server can read (a `404`) - the
|
|
99
|
+
* common, expected answer for a message that merely has an attachment - and rejects for any other failure.
|
|
100
|
+
*/
|
|
101
|
+
export declare function getMessageInvite(messageUid: string, client?: ApiClient): Promise<MessageInvite | null>;
|
|
102
|
+
/**
|
|
103
|
+
* Answers an invitation. The server puts the meeting on the reader's calendar for `"accepted"`/`"tentative"` (or takes it
|
|
104
|
+
* off for `"declined"`) and sends the organizer the matching iTIP REPLY; for a `PUBLISH`ed event (which has no organizer to
|
|
105
|
+
* answer) `"accepted"` only adds it to the calendar. Resolves with the invitation as it now stands.
|
|
106
|
+
*/
|
|
107
|
+
export declare function respondToMessageInvite(messageUid: string, responseStatus: InviteResponse, client?: ApiClient): Promise<MessageInvite>;
|
|
108
|
+
/** Takes a canceled meeting off the reader's calendar. Resolves with the invitation as it now stands. */
|
|
109
|
+
export declare function removeMessageInvite(messageUid: string, client?: ApiClient): Promise<MessageInvite>;
|
|
110
|
+
/** A different time to suggest to the organizer. */
|
|
111
|
+
export interface ProposedTime {
|
|
112
|
+
/** ISO 8601 instants. */
|
|
113
|
+
startDate: string;
|
|
114
|
+
endDate: string;
|
|
115
|
+
/** A note to the organizer, sent with the proposal. */
|
|
116
|
+
comment?: string;
|
|
117
|
+
}
|
|
118
|
+
/** Proposes a different time to the organizer of a `REQUEST` (an iTIP `COUNTER` sent by the server). Resolves with the invitation as it now stands. */
|
|
119
|
+
export declare function proposeNewTime(messageUid: string, proposal: ProposedTime, client?: ApiClient): Promise<MessageInvite>;
|
|
120
|
+
/** Accepts an attendee's proposed time (a `COUNTER`) for a meeting the reader organizes: the server moves the event and sends the attendees the update. Resolves with the invitation as it now stands. */
|
|
121
|
+
export declare function acceptProposal(messageUid: string, client?: ApiClient): Promise<MessageInvite>;
|
|
@@ -0,0 +1,54 @@
|
|
|
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/invite` surface - the calendar invitation (iMIP: an
|
|
6
|
+
* `.ics` attachment carrying an iTIP `METHOD`) a mail message may hold, read for the reading pane's invitation card. The
|
|
7
|
+
* server does all the work of an answer: it puts the meeting on the reader's calendar (or takes it off), and sends the
|
|
8
|
+
* iTIP REPLY to the organizer. The client only reads the state and asks for a change; every call returns the invitation as
|
|
9
|
+
* it now stands, ready to draw. */
|
|
10
|
+
import { ApiRequestError, withClient } from "../util/api.js";
|
|
11
|
+
/** `client`, given by every function below, is an explicit `ApiClient` from `createApiClient()` (e.g. one
|
|
12
|
+
* account of a multi-account app) to call instead of the default global `apiFetch()` - see `withClient()`'s
|
|
13
|
+
* own doc comment in `util/api.ts`. Omitted (the default), every function here behaves exactly as before. */
|
|
14
|
+
/**
|
|
15
|
+
* Reads the invitation a message carries. Resolves `null` when the message has none the server can read (a `404`) - the
|
|
16
|
+
* common, expected answer for a message that merely has an attachment - and rejects for any other failure.
|
|
17
|
+
*/
|
|
18
|
+
export async function getMessageInvite(messageUid, client) {
|
|
19
|
+
try {
|
|
20
|
+
return await withClient(client, `/mail/calendar-events/invite/${encodeURIComponent(messageUid)}`);
|
|
21
|
+
}
|
|
22
|
+
catch (err) {
|
|
23
|
+
if (err instanceof ApiRequestError && err.status === 404) {
|
|
24
|
+
return null;
|
|
25
|
+
}
|
|
26
|
+
throw err;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Answers an invitation. The server puts the meeting on the reader's calendar for `"accepted"`/`"tentative"` (or takes it
|
|
31
|
+
* off for `"declined"`) and sends the organizer the matching iTIP REPLY; for a `PUBLISH`ed event (which has no organizer to
|
|
32
|
+
* answer) `"accepted"` only adds it to the calendar. Resolves with the invitation as it now stands.
|
|
33
|
+
*/
|
|
34
|
+
export function respondToMessageInvite(messageUid, responseStatus, client) {
|
|
35
|
+
return withClient(client, `/mail/calendar-events/invite/${encodeURIComponent(messageUid)}/respond`, {
|
|
36
|
+
method: "POST",
|
|
37
|
+
body: JSON.stringify({ responseStatus }),
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
/** Takes a canceled meeting off the reader's calendar. Resolves with the invitation as it now stands. */
|
|
41
|
+
export function removeMessageInvite(messageUid, client) {
|
|
42
|
+
return withClient(client, `/mail/calendar-events/invite/${encodeURIComponent(messageUid)}/remove`, { method: "POST" });
|
|
43
|
+
}
|
|
44
|
+
/** Proposes a different time to the organizer of a `REQUEST` (an iTIP `COUNTER` sent by the server). Resolves with the invitation as it now stands. */
|
|
45
|
+
export function proposeNewTime(messageUid, proposal, client) {
|
|
46
|
+
return withClient(client, `/mail/calendar-events/invite/${encodeURIComponent(messageUid)}/propose`, {
|
|
47
|
+
method: "POST",
|
|
48
|
+
body: JSON.stringify(proposal),
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
/** Accepts an attendee's proposed time (a `COUNTER`) for a meeting the reader organizes: the server moves the event and sends the attendees the update. Resolves with the invitation as it now stands. */
|
|
52
|
+
export function acceptProposal(messageUid, client) {
|
|
53
|
+
return withClient(client, `/mail/calendar-events/invite/${encodeURIComponent(messageUid)}/accept-proposal`, { method: "POST" });
|
|
54
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* RFC5545 recurrence expansion, entirely client-side — `@rapidmx/restapi` stores/returns
|
|
3
|
+
* `RecurrenceRule` as-is and does no expansion of its own (see `calendarApi.ts`'s own header
|
|
4
|
+
* comment). Built on the `rrule` package.
|
|
5
|
+
*/
|
|
6
|
+
import * as RRuleNS from "rrule";
|
|
7
|
+
import { CalendarEvent, RecurrenceRule, WeekdayCode } from "./calendarApi.js";
|
|
8
|
+
/** Extracted so the CJS-interop fallback branch can be exercised directly with a plain object,
|
|
9
|
+
* without needing to fight a module mock into reproducing Node's exact interop shape. */
|
|
10
|
+
export declare function resolveRRuleExport(ns: typeof RRuleNS): typeof RRuleNS.RRule;
|
|
11
|
+
/**
|
|
12
|
+
* Builds an `RRule` instance from this app's `RecurrenceRule` shape, anchored at `dtstart`. Pass the
|
|
13
|
+
* event's IANA `tzid` so the rule carries it (e.g. `DTSTART;TZID=America/New_York:...` from
|
|
14
|
+
* `.toString()`) — note that, per `rrule`'s own convention, a rule with a non-UTC `tzid` expects
|
|
15
|
+
* `dtstart` to be a "floating" wall-clock time expressed as a UTC `Date` and rezones its generated
|
|
16
|
+
* dates using the *runtime's* local zone, which is why `expandOccurrences()` below does its own
|
|
17
|
+
* timezone conversion instead of relying on this.
|
|
18
|
+
*/
|
|
19
|
+
export declare function buildRRule(rule: RecurrenceRule, dtstart: Date, tzid?: string): RRuleNS.RRule;
|
|
20
|
+
/** A single expanded occurrence of a (possibly recurring) `CalendarEvent`, ready to render on a grid. */
|
|
21
|
+
export interface CalendarOccurrence extends CalendarEvent {
|
|
22
|
+
/** A key unique per occurrence (`${event.uid}::${occurrence start}`) — use this for React `key`s and
|
|
23
|
+
* drag-and-drop ids, since a recurring event's `uid` alone isn't unique across its occurrences. */
|
|
24
|
+
occurrenceKey: string;
|
|
25
|
+
/** `true` for a generated occurrence of a recurring event (as opposed to the stored master record, or
|
|
26
|
+
* a genuinely non-recurring event) — moving/resizing one calls `updateCalendarEvent` differently (see
|
|
27
|
+
* the calendar page's own drag handlers) since it must detach into its own standalone event. */
|
|
28
|
+
isRecurringOccurrence: boolean;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Converts an instant to the "wall-clock as UTC" milliseconds recurrence expansion works in for an event
|
|
32
|
+
* with this `timezone`/`allDay` - UTC for an all-day event (stored as UTC-midnight dates), the event's IANA
|
|
33
|
+
* zone otherwise (the runtime's local zone when empty or unrecognized). Exported for `calendarMutations.ts`,
|
|
34
|
+
* which shifts a series' exception dates by the same wall-clock delta as its start.
|
|
35
|
+
*/
|
|
36
|
+
export declare function toEventWallClock(instantMs: number, timezone: string | undefined, allDay: boolean | undefined): number;
|
|
37
|
+
/** Inverse of `toEventWallClock()` (DST gaps/overlaps resolved per RFC 5545 - see `ianaZone()`). */
|
|
38
|
+
export declare function fromEventWallClock(wallMs: number, timezone: string | undefined, allDay: boolean | undefined): number;
|
|
39
|
+
/**
|
|
40
|
+
* Expands `event` into every occurrence whose interval overlaps `[rangeStart, rangeEnd]`. A
|
|
41
|
+
* non-recurring event yields itself (in a one-element array) if it overlaps, or `[]` otherwise —
|
|
42
|
+
* callers don't need to special-case recurring vs. not.
|
|
43
|
+
*
|
|
44
|
+
* Recurrence is expanded in the event's own `timezone` (an IANA zone id; an empty or unrecognized
|
|
45
|
+
* value falls back to the runtime's local zone, i.e. floating time), so every occurrence keeps the
|
|
46
|
+
* master's local wall-clock start/end time and local weekday — a weekly Monday 23:00
|
|
47
|
+
* America/New_York event stays on Monday 23:00 New York time across DST changes, rather than being
|
|
48
|
+
* expanded on the UTC weekday/time of its first instance. An all-day event is the exception: its dates are
|
|
49
|
+
* UTC-midnight date-only values, so it expands in UTC regardless of `timezone` - expanding a
|
|
50
|
+
* `2026-09-14T00:00Z` Monday in America/New_York would otherwise see a Sunday-evening start and put every
|
|
51
|
+
* occurrence on the wrong date. A timed occurrence that falls in a DST gap starts at the pre-transition
|
|
52
|
+
* offset (RFC 5545) and keeps its wall-clock duration.
|
|
53
|
+
*/
|
|
54
|
+
export declare function expandOccurrences(event: CalendarEvent, rangeStart: Date, rangeEnd: Date): CalendarOccurrence[];
|
|
55
|
+
/** Expands every event in `events` and flattens the result — the usual entry point for a grid view. */
|
|
56
|
+
export declare function expandAllOccurrences(events: CalendarEvent[], rangeStart: Date, rangeEnd: Date): CalendarOccurrence[];
|
|
57
|
+
/** A human-readable summary of `rule` (e.g. "every 2 weeks on Monday, Wednesday until Jan 1, 2027"). */
|
|
58
|
+
export declare function describeRecurrence(rule: RecurrenceRule): string;
|
|
59
|
+
export declare const WEEKDAY_CODES: WeekdayCode[];
|
|
60
|
+
export declare const WEEKDAY_LABELS: Record<WeekdayCode, string>;
|