@rapidmx/web-client 0.9.0 → 0.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (443) hide show
  1. package/README.md +373 -88
  2. package/apps/admin/_layout.tsx +8 -2
  3. package/apps/admin/index.tsx +7 -1
  4. package/apps/admin/ingest-queue/index.tsx +2 -1
  5. package/apps/admin/mailboxes/[uid].tsx +23 -10
  6. package/apps/admin/quarantine/index.tsx +2 -1
  7. package/apps/admin/signing-certificates/index.tsx +343 -0
  8. package/apps/escrow/_layout.tsx +8 -2
  9. package/apps/shared/appearance/AppearanceForm.tsx +392 -0
  10. package/apps/shared/appearance/AppearanceHead.tsx +49 -0
  11. package/apps/shared/appearance/AppearanceProvider.tsx +470 -0
  12. package/apps/shared/appearance/ColorField.tsx +107 -0
  13. package/apps/shared/appearance/appearanceCache.ts +106 -0
  14. package/apps/shared/appearance/appearanceContext.ts +77 -0
  15. package/apps/shared/appearance/bootScript.ts +35 -0
  16. package/apps/shared/appearance/color.ts +169 -0
  17. package/apps/shared/appearance/photo.ts +88 -0
  18. package/apps/shared/appearance/resolvedTheme.ts +67 -0
  19. package/apps/shared/appearance/theme.ts +355 -0
  20. package/apps/shared/auth/accountUrl.ts +9 -0
  21. package/apps/shared/auth/adminAccess.ts +99 -0
  22. package/apps/shared/components/admin/layout/AdminShell.tsx +22 -10
  23. package/apps/shared/components/admin/mailboxes/ShareAccessCard.tsx +107 -60
  24. package/apps/shared/components/admin/settings/BrandingForm.tsx +24 -0
  25. package/apps/shared/components/admin/settings/DomainDnsSetup.tsx +2 -1
  26. package/apps/shared/components/admin/settings/PluginsManager.tsx +228 -25
  27. package/apps/shared/components/admin/setup/SetupWizard.tsx +2 -1
  28. package/apps/shared/components/calendar/CalendarListSidebar.tsx +4 -5
  29. package/apps/shared/components/calendar/layout/CalendarShell.tsx +8 -2
  30. package/apps/shared/components/contacts/ContactForm.tsx +11 -5
  31. package/apps/shared/components/contacts/ContactsSidebar.tsx +5 -3
  32. package/apps/shared/components/contacts/ContactsToolbar.tsx +98 -115
  33. package/apps/shared/components/contacts/layout/ContactsShell.tsx +25 -8
  34. package/apps/shared/components/escrow/layout/EscrowShell.tsx +13 -6
  35. package/apps/shared/components/layout/AppShell.tsx +477 -288
  36. package/apps/shared/components/layout/BrandingChrome.tsx +200 -13
  37. package/apps/shared/components/layout/KeyEnrollmentGate.tsx +398 -389
  38. package/apps/shared/components/layout/MailboxProvisioning.tsx +168 -164
  39. package/apps/shared/components/layout/RailIcon.tsx +100 -0
  40. package/apps/shared/components/layout/ResponsiveToolbar.tsx +315 -0
  41. package/apps/shared/components/layout/ThemeSwitch.tsx +84 -0
  42. package/apps/shared/components/layout/UserMenu.tsx +372 -185
  43. package/apps/shared/components/mail/ConversationList.tsx +271 -262
  44. package/apps/shared/components/mail/ConversationThreadPane.tsx +147 -94
  45. package/apps/shared/components/mail/LazyReadingPane.tsx +113 -0
  46. package/apps/shared/components/mail/MailSelectionBar.tsx +227 -222
  47. package/apps/shared/components/mail/MessageDetailPane.tsx +1537 -1387
  48. package/apps/shared/components/mail/OutboxBadge.tsx +44 -0
  49. package/apps/shared/components/mail/OutboxRowStatus.tsx +31 -0
  50. package/apps/shared/components/mail/compose/ComposeContext.tsx +312 -160
  51. package/apps/shared/components/mail/compose/ComposeToolbar.tsx +422 -418
  52. package/apps/shared/components/mail/compose/ComposeWindow.tsx +1644 -1736
  53. package/apps/shared/components/mail/compose/ComposeWindowPlaceholder.tsx +111 -0
  54. package/apps/shared/components/mail/compose/RichTextEditor.tsx +147 -118
  55. package/apps/shared/components/mail/compose/composePerf.ts +46 -0
  56. package/apps/shared/components/mail/compose/encryptionRequirement.ts +86 -0
  57. package/apps/shared/components/mail/compose/quotedBody.ts +161 -100
  58. package/apps/shared/components/mail/layout/MailShell.tsx +490 -472
  59. package/apps/shared/components/mail/reading/EncryptedBody.tsx +65 -0
  60. package/apps/shared/components/mail/reading/EncryptedPreview.tsx +35 -0
  61. package/apps/shared/components/mail/reading/MessageBody.tsx +240 -0
  62. package/apps/shared/components/mail/reading/MessageCard.tsx +174 -0
  63. package/apps/shared/components/mail/reading/bodyContent.ts +100 -0
  64. package/apps/shared/components/mail/reading/bodyHtml.ts +298 -0
  65. package/apps/shared/components/mail/reading/color.ts +245 -0
  66. package/apps/shared/components/mail/reading/frameControl.ts +142 -0
  67. package/apps/shared/components/mail/reading/frameDocument.ts +123 -0
  68. package/apps/shared/components/mail/reading/safeDocument.ts +24 -0
  69. package/apps/shared/components/mail/reading/themeAdaptation.ts +221 -0
  70. package/apps/shared/components/mail/reading/themeSurface.ts +90 -0
  71. package/apps/shared/components/mail/reading/viewOriginal.ts +38 -0
  72. package/apps/shared/components/mail/unreadStyle.tsx +75 -0
  73. package/apps/shared/components/settings/SigningCertificateCard.tsx +344 -0
  74. package/apps/shared/components/settings/layout/SettingsShell.tsx +253 -240
  75. package/apps/shared/components/sharing/PrincipalPicker.tsx +145 -0
  76. package/apps/shared/components/tasks/TasksSidebar.tsx +5 -3
  77. package/apps/shared/components/tasks/layout/TasksShell.tsx +24 -8
  78. package/apps/shared/keyboard/GlobalShortcuts.tsx +51 -0
  79. package/apps/shared/keyboard/ShortcutProvider.tsx +62 -0
  80. package/apps/shared/keyboard/ShortcutsDialog.tsx +84 -0
  81. package/apps/shared/keyboard/dispatch.ts +124 -0
  82. package/apps/shared/keyboard/format.ts +89 -0
  83. package/apps/shared/keyboard/keymap.ts +114 -0
  84. package/apps/shared/keyboard/match.ts +44 -0
  85. package/apps/shared/keyboard/parse.ts +136 -0
  86. package/apps/shared/keyboard/platform.ts +34 -0
  87. package/apps/shared/keyboard/registry.ts +65 -0
  88. package/apps/shared/keyboard/targets.ts +79 -0
  89. package/apps/shared/keyboard/useShortcut.ts +50 -0
  90. package/apps/shared/keyboard/useShortcutProps.ts +17 -0
  91. package/apps/shared/mail/folderCounts.ts +308 -0
  92. package/apps/shared/mail/folderTree.ts +143 -0
  93. package/apps/shared/mail/listSnapshots.ts +87 -0
  94. package/apps/shared/mail/messageReadState.ts +85 -0
  95. package/apps/shared/mail/newMailNotifications.ts +183 -0
  96. package/apps/shared/mail/outbox/UnlockBridge.tsx +23 -0
  97. package/apps/shared/mail/outbox/composeBridge.ts +69 -0
  98. package/apps/shared/mail/outbox/outboxState.ts +88 -0
  99. package/apps/shared/mail/outbox/pendingSends.ts +146 -0
  100. package/apps/shared/mail/outbox/sendDecision.ts +157 -0
  101. package/apps/shared/mail/outbox/sendJob.ts +427 -0
  102. package/apps/shared/mail/outbox/sendOutcomes.ts +146 -0
  103. package/apps/shared/mail/outbox/sendState.ts +35 -0
  104. package/apps/shared/mail/outbox/useOutboxStatus.ts +61 -0
  105. package/apps/shared/mail/useMailConnection.ts +203 -0
  106. package/apps/shared/mail/useMailLiveUpdates.ts +277 -224
  107. package/apps/shared/mail/useMarkMessageRead.ts +47 -0
  108. package/apps/shared/mail/useNewMailNotifications.ts +178 -0
  109. package/apps/shared/mail/useUnreadTitle.ts +42 -0
  110. package/apps/shared/navigation/AppRouter.tsx +300 -0
  111. package/apps/shared/navigation/appHrefs.ts +23 -0
  112. package/apps/shared/navigation/frameContext.tsx +35 -0
  113. package/apps/shared/navigation/idle.ts +45 -0
  114. package/apps/shared/navigation/routerContext.tsx +83 -0
  115. package/apps/shared/navigation/routes.ts +72 -0
  116. package/apps/shared/notifications/NotificationCenter.tsx +215 -0
  117. package/apps/shared/notifications/NotificationHistoryDialog.tsx +90 -0
  118. package/apps/shared/notifications/apiErrors.ts +98 -0
  119. package/apps/shared/notifications/headerOffset.ts +35 -0
  120. package/apps/shared/notifications/pushStatus.ts +56 -0
  121. package/apps/shared/notifications/store.ts +549 -0
  122. package/apps/shared/notifications/systemErrors.ts +63 -0
  123. package/apps/shared/notifications/useNotifications.ts +41 -0
  124. package/apps/shared/search/LocalIndexLifecycle.tsx +114 -98
  125. package/apps/shared/signing/enrollmentStorage.ts +33 -0
  126. package/apps/shared/signing/enrollmentTracker.ts +385 -0
  127. package/apps/shared/signing/enrollmentView.ts +251 -0
  128. package/apps/shared/signing/signingInfo.ts +58 -0
  129. package/apps/shared/signing/useNow.ts +19 -0
  130. package/apps/shared/signing/useSigningEnrollmentWatcher.ts +90 -0
  131. package/apps/shared/styles/app.css +108 -10
  132. package/apps/www/_layout.tsx +8 -2
  133. package/apps/www/_routedPage.tsx +24 -0
  134. package/apps/www/_routes.ts +36 -0
  135. package/apps/www/calendar/index.tsx +64 -33
  136. package/apps/www/contacts/[uid].tsx +109 -107
  137. package/apps/www/contacts/index.tsx +62 -42
  138. package/apps/www/index.tsx +2291 -1917
  139. package/apps/www/messages/[uid].tsx +108 -101
  140. package/apps/www/settings/appearance/index.tsx +21 -0
  141. package/apps/www/settings/auto-reply/index.tsx +7 -8
  142. package/apps/www/settings/encryption/index.tsx +1287 -1249
  143. package/apps/www/settings/filters/[uid].tsx +7 -2
  144. package/apps/www/settings/filters/index.tsx +102 -99
  145. package/apps/www/settings/filters/new/index.tsx +140 -133
  146. package/apps/www/settings/labels/index.tsx +204 -201
  147. package/apps/www/settings/privacy/index.tsx +7 -9
  148. package/apps/www/settings/read-receipts/index.tsx +7 -8
  149. package/apps/www/settings/sharing/index.tsx +256 -274
  150. package/apps/www/settings/signatures/[uid].tsx +172 -167
  151. package/apps/www/settings/signatures/index.tsx +88 -85
  152. package/apps/www/settings/signatures/new/index.tsx +135 -129
  153. package/apps/www/tasks/index.tsx +29 -18
  154. package/dist/apps/admin/_layout.d.ts +5 -1
  155. package/dist/apps/admin/_layout.js +3 -2
  156. package/dist/apps/admin/index.js +3 -2
  157. package/dist/apps/admin/ingest-queue/index.js +2 -1
  158. package/dist/apps/admin/mailboxes/[uid].js +9 -6
  159. package/dist/apps/admin/quarantine/index.js +2 -1
  160. package/dist/apps/admin/signing-certificates/index.d.ts +3 -0
  161. package/dist/apps/admin/signing-certificates/index.js +161 -0
  162. package/dist/apps/escrow/_layout.d.ts +5 -1
  163. package/dist/apps/escrow/_layout.js +3 -2
  164. package/dist/apps/shared/appearance/AppearanceForm.d.ts +7 -0
  165. package/dist/apps/shared/appearance/AppearanceForm.js +131 -0
  166. package/dist/apps/shared/appearance/AppearanceHead.d.ts +15 -0
  167. package/dist/apps/shared/appearance/AppearanceHead.js +31 -0
  168. package/dist/apps/shared/appearance/AppearanceProvider.d.ts +32 -0
  169. package/dist/apps/shared/appearance/AppearanceProvider.js +390 -0
  170. package/dist/apps/shared/appearance/ColorField.d.ts +22 -0
  171. package/dist/apps/shared/appearance/ColorField.js +40 -0
  172. package/dist/apps/shared/appearance/appearanceCache.d.ts +45 -0
  173. package/dist/apps/shared/appearance/appearanceCache.js +80 -0
  174. package/dist/apps/shared/appearance/appearanceContext.d.ts +45 -0
  175. package/dist/apps/shared/appearance/appearanceContext.js +29 -0
  176. package/dist/apps/shared/appearance/bootScript.d.ts +16 -0
  177. package/dist/apps/shared/appearance/bootScript.js +33 -0
  178. package/dist/apps/shared/appearance/color.d.ts +65 -0
  179. package/dist/apps/shared/appearance/color.js +132 -0
  180. package/dist/apps/shared/appearance/photo.d.ts +17 -0
  181. package/dist/apps/shared/appearance/photo.js +79 -0
  182. package/dist/apps/shared/appearance/resolvedTheme.d.ts +21 -0
  183. package/dist/apps/shared/appearance/resolvedTheme.js +55 -0
  184. package/dist/apps/shared/appearance/theme.d.ts +111 -0
  185. package/dist/apps/shared/appearance/theme.js +251 -0
  186. package/dist/apps/shared/auth/accountUrl.d.ts +2 -0
  187. package/dist/apps/shared/auth/accountUrl.js +8 -0
  188. package/dist/apps/shared/auth/adminAccess.d.ts +30 -0
  189. package/dist/apps/shared/auth/adminAccess.js +89 -0
  190. package/dist/apps/shared/components/admin/layout/AdminShell.d.ts +1 -1
  191. package/dist/apps/shared/components/admin/layout/AdminShell.js +16 -6
  192. package/dist/apps/shared/components/admin/mailboxes/ShareAccessCard.d.ts +10 -5
  193. package/dist/apps/shared/components/admin/mailboxes/ShareAccessCard.js +49 -34
  194. package/dist/apps/shared/components/admin/settings/BrandingForm.d.ts +2 -0
  195. package/dist/apps/shared/components/admin/settings/BrandingForm.js +7 -1
  196. package/dist/apps/shared/components/admin/settings/DomainDnsSetup.js +1 -1
  197. package/dist/apps/shared/components/admin/settings/PluginsManager.js +106 -20
  198. package/dist/apps/shared/components/admin/setup/SetupWizard.js +2 -1
  199. package/dist/apps/shared/components/calendar/CalendarListSidebar.js +8 -8
  200. package/dist/apps/shared/components/calendar/layout/CalendarShell.d.ts +1 -1
  201. package/dist/apps/shared/components/calendar/layout/CalendarShell.js +8 -4
  202. package/dist/apps/shared/components/contacts/ContactForm.js +1 -1
  203. package/dist/apps/shared/components/contacts/ContactsSidebar.js +4 -2
  204. package/dist/apps/shared/components/contacts/ContactsToolbar.d.ts +6 -2
  205. package/dist/apps/shared/components/contacts/ContactsToolbar.js +28 -10
  206. package/dist/apps/shared/components/contacts/layout/ContactsShell.d.ts +1 -1
  207. package/dist/apps/shared/components/contacts/layout/ContactsShell.js +19 -6
  208. package/dist/apps/shared/components/escrow/layout/EscrowShell.js +7 -4
  209. package/dist/apps/shared/components/layout/AppShell.d.ts +34 -4
  210. package/dist/apps/shared/components/layout/AppShell.js +122 -17
  211. package/dist/apps/shared/components/layout/BrandingChrome.d.ts +69 -10
  212. package/dist/apps/shared/components/layout/BrandingChrome.js +140 -12
  213. package/dist/apps/shared/components/layout/KeyEnrollmentGate.js +10 -9
  214. package/dist/apps/shared/components/layout/MailboxProvisioning.js +3 -1
  215. package/dist/apps/shared/components/layout/RailIcon.d.ts +21 -0
  216. package/dist/apps/shared/components/layout/RailIcon.js +85 -0
  217. package/dist/apps/shared/components/layout/ResponsiveToolbar.d.ts +55 -0
  218. package/dist/apps/shared/components/layout/ResponsiveToolbar.js +199 -0
  219. package/dist/apps/shared/components/layout/ThemeSwitch.d.ts +9 -0
  220. package/dist/apps/shared/components/layout/ThemeSwitch.js +54 -0
  221. package/dist/apps/shared/components/layout/UserMenu.d.ts +25 -3
  222. package/dist/apps/shared/components/layout/UserMenu.js +88 -7
  223. package/dist/apps/shared/components/mail/ConversationList.js +5 -11
  224. package/dist/apps/shared/components/mail/ConversationThreadPane.d.ts +6 -2
  225. package/dist/apps/shared/components/mail/ConversationThreadPane.js +87 -40
  226. package/dist/apps/shared/components/mail/LazyReadingPane.d.ts +9 -0
  227. package/dist/apps/shared/components/mail/LazyReadingPane.js +83 -0
  228. package/dist/apps/shared/components/mail/MailSelectionBar.d.ts +6 -4
  229. package/dist/apps/shared/components/mail/MailSelectionBar.js +11 -4
  230. package/dist/apps/shared/components/mail/MessageDetailPane.d.ts +25 -8
  231. package/dist/apps/shared/components/mail/MessageDetailPane.js +167 -73
  232. package/dist/apps/shared/components/mail/OutboxBadge.d.ts +17 -0
  233. package/dist/apps/shared/components/mail/OutboxBadge.js +18 -0
  234. package/dist/apps/shared/components/mail/OutboxRowStatus.d.ts +10 -0
  235. package/dist/apps/shared/components/mail/OutboxRowStatus.js +19 -0
  236. package/dist/apps/shared/components/mail/compose/ComposeContext.d.ts +38 -0
  237. package/dist/apps/shared/components/mail/compose/ComposeContext.js +97 -6
  238. package/dist/apps/shared/components/mail/compose/ComposeToolbar.js +4 -3
  239. package/dist/apps/shared/components/mail/compose/ComposeWindow.d.ts +3 -2
  240. package/dist/apps/shared/components/mail/compose/ComposeWindow.js +316 -339
  241. package/dist/apps/shared/components/mail/compose/ComposeWindowPlaceholder.d.ts +19 -0
  242. package/dist/apps/shared/components/mail/compose/ComposeWindowPlaceholder.js +33 -0
  243. package/dist/apps/shared/components/mail/compose/RichTextEditor.d.ts +9 -1
  244. package/dist/apps/shared/components/mail/compose/RichTextEditor.js +20 -2
  245. package/dist/apps/shared/components/mail/compose/composePerf.d.ts +16 -0
  246. package/dist/apps/shared/components/mail/compose/composePerf.js +41 -0
  247. package/dist/apps/shared/components/mail/compose/encryptionRequirement.d.ts +49 -0
  248. package/dist/apps/shared/components/mail/compose/encryptionRequirement.js +35 -0
  249. package/dist/apps/shared/components/mail/compose/quotedBody.d.ts +13 -0
  250. package/dist/apps/shared/components/mail/compose/quotedBody.js +67 -11
  251. package/dist/apps/shared/components/mail/layout/MailShell.d.ts +14 -4
  252. package/dist/apps/shared/components/mail/layout/MailShell.js +90 -104
  253. package/dist/apps/shared/components/mail/reading/EncryptedBody.d.ts +21 -0
  254. package/dist/apps/shared/components/mail/reading/EncryptedBody.js +22 -0
  255. package/dist/apps/shared/components/mail/reading/EncryptedPreview.d.ts +18 -0
  256. package/dist/apps/shared/components/mail/reading/EncryptedPreview.js +22 -0
  257. package/dist/apps/shared/components/mail/reading/MessageBody.d.ts +32 -0
  258. package/dist/apps/shared/components/mail/reading/MessageBody.js +136 -0
  259. package/dist/apps/shared/components/mail/reading/MessageCard.d.ts +62 -0
  260. package/dist/apps/shared/components/mail/reading/MessageCard.js +58 -0
  261. package/dist/apps/shared/components/mail/reading/bodyContent.d.ts +38 -0
  262. package/dist/apps/shared/components/mail/reading/bodyContent.js +84 -0
  263. package/dist/apps/shared/components/mail/reading/bodyHtml.d.ts +47 -0
  264. package/dist/apps/shared/components/mail/reading/bodyHtml.js +267 -0
  265. package/dist/apps/shared/components/mail/reading/color.d.ts +63 -0
  266. package/dist/apps/shared/components/mail/reading/color.js +201 -0
  267. package/dist/apps/shared/components/mail/reading/frameControl.d.ts +33 -0
  268. package/dist/apps/shared/components/mail/reading/frameControl.js +120 -0
  269. package/dist/apps/shared/components/mail/reading/frameDocument.d.ts +52 -0
  270. package/dist/apps/shared/components/mail/reading/frameDocument.js +98 -0
  271. package/dist/apps/shared/components/mail/reading/safeDocument.d.ts +3 -0
  272. package/dist/apps/shared/components/mail/reading/safeDocument.js +12 -0
  273. package/dist/apps/shared/components/mail/reading/themeAdaptation.d.ts +56 -0
  274. package/dist/apps/shared/components/mail/reading/themeAdaptation.js +144 -0
  275. package/dist/apps/shared/components/mail/reading/themeSurface.d.ts +17 -0
  276. package/dist/apps/shared/components/mail/reading/themeSurface.js +83 -0
  277. package/dist/apps/shared/components/mail/reading/viewOriginal.d.ts +9 -0
  278. package/dist/apps/shared/components/mail/reading/viewOriginal.js +32 -0
  279. package/dist/apps/shared/components/mail/unreadStyle.d.ts +45 -0
  280. package/dist/apps/shared/components/mail/unreadStyle.js +61 -0
  281. package/dist/apps/shared/components/settings/SigningCertificateCard.d.ts +32 -0
  282. package/dist/apps/shared/components/settings/SigningCertificateCard.js +98 -0
  283. package/dist/apps/shared/components/settings/layout/SettingsShell.d.ts +1 -1
  284. package/dist/apps/shared/components/settings/layout/SettingsShell.js +16 -5
  285. package/dist/apps/shared/components/sharing/PrincipalPicker.d.ts +26 -0
  286. package/dist/apps/shared/components/sharing/PrincipalPicker.js +77 -0
  287. package/dist/apps/shared/components/tasks/TasksSidebar.js +4 -2
  288. package/dist/apps/shared/components/tasks/layout/TasksShell.d.ts +1 -1
  289. package/dist/apps/shared/components/tasks/layout/TasksShell.js +18 -6
  290. package/dist/apps/shared/keyboard/GlobalShortcuts.d.ts +14 -0
  291. package/dist/apps/shared/keyboard/GlobalShortcuts.js +37 -0
  292. package/dist/apps/shared/keyboard/ShortcutProvider.d.ts +20 -0
  293. package/dist/apps/shared/keyboard/ShortcutProvider.js +52 -0
  294. package/dist/apps/shared/keyboard/ShortcutsDialog.d.ts +14 -0
  295. package/dist/apps/shared/keyboard/ShortcutsDialog.js +42 -0
  296. package/dist/apps/shared/keyboard/dispatch.d.ts +16 -0
  297. package/dist/apps/shared/keyboard/dispatch.js +109 -0
  298. package/dist/apps/shared/keyboard/format.d.ts +12 -0
  299. package/dist/apps/shared/keyboard/format.js +74 -0
  300. package/dist/apps/shared/keyboard/keymap.d.ts +294 -0
  301. package/dist/apps/shared/keyboard/keymap.js +84 -0
  302. package/dist/apps/shared/keyboard/match.d.ts +20 -0
  303. package/dist/apps/shared/keyboard/match.js +31 -0
  304. package/dist/apps/shared/keyboard/parse.d.ts +31 -0
  305. package/dist/apps/shared/keyboard/parse.js +107 -0
  306. package/dist/apps/shared/keyboard/platform.d.ts +15 -0
  307. package/dist/apps/shared/keyboard/platform.js +22 -0
  308. package/dist/apps/shared/keyboard/registry.d.ts +39 -0
  309. package/dist/apps/shared/keyboard/registry.js +33 -0
  310. package/dist/apps/shared/keyboard/targets.d.ts +14 -0
  311. package/dist/apps/shared/keyboard/targets.js +67 -0
  312. package/dist/apps/shared/keyboard/useShortcut.d.ts +19 -0
  313. package/dist/apps/shared/keyboard/useShortcut.js +35 -0
  314. package/dist/apps/shared/keyboard/useShortcutProps.d.ts +10 -0
  315. package/dist/apps/shared/keyboard/useShortcutProps.js +15 -0
  316. package/dist/apps/shared/mail/folderCounts.d.ts +78 -0
  317. package/dist/apps/shared/mail/folderCounts.js +218 -0
  318. package/dist/apps/shared/mail/folderTree.d.ts +55 -0
  319. package/dist/apps/shared/mail/folderTree.js +116 -0
  320. package/dist/apps/shared/mail/listSnapshots.d.ts +46 -0
  321. package/dist/apps/shared/mail/listSnapshots.js +43 -0
  322. package/dist/apps/shared/mail/messageReadState.d.ts +32 -0
  323. package/dist/apps/shared/mail/messageReadState.js +63 -0
  324. package/dist/apps/shared/mail/newMailNotifications.d.ts +62 -0
  325. package/dist/apps/shared/mail/newMailNotifications.js +138 -0
  326. package/dist/apps/shared/mail/outbox/UnlockBridge.d.ts +5 -0
  327. package/dist/apps/shared/mail/outbox/UnlockBridge.js +18 -0
  328. package/dist/apps/shared/mail/outbox/composeBridge.d.ts +34 -0
  329. package/dist/apps/shared/mail/outbox/composeBridge.js +32 -0
  330. package/dist/apps/shared/mail/outbox/outboxState.d.ts +41 -0
  331. package/dist/apps/shared/mail/outbox/outboxState.js +42 -0
  332. package/dist/apps/shared/mail/outbox/pendingSends.d.ts +39 -0
  333. package/dist/apps/shared/mail/outbox/pendingSends.js +109 -0
  334. package/dist/apps/shared/mail/outbox/sendDecision.d.ts +80 -0
  335. package/dist/apps/shared/mail/outbox/sendDecision.js +94 -0
  336. package/dist/apps/shared/mail/outbox/sendJob.d.ts +68 -0
  337. package/dist/apps/shared/mail/outbox/sendJob.js +319 -0
  338. package/dist/apps/shared/mail/outbox/sendOutcomes.d.ts +3 -0
  339. package/dist/apps/shared/mail/outbox/sendOutcomes.js +141 -0
  340. package/dist/apps/shared/mail/outbox/sendState.d.ts +25 -0
  341. package/dist/apps/shared/mail/outbox/sendState.js +8 -0
  342. package/dist/apps/shared/mail/outbox/useOutboxStatus.d.ts +11 -0
  343. package/dist/apps/shared/mail/outbox/useOutboxStatus.js +49 -0
  344. package/dist/apps/shared/mail/useMailConnection.d.ts +56 -0
  345. package/dist/apps/shared/mail/useMailConnection.js +138 -0
  346. package/dist/apps/shared/mail/useMailLiveUpdates.d.ts +29 -9
  347. package/dist/apps/shared/mail/useMailLiveUpdates.js +60 -32
  348. package/dist/apps/shared/mail/useMarkMessageRead.d.ts +12 -0
  349. package/dist/apps/shared/mail/useMarkMessageRead.js +44 -0
  350. package/dist/apps/shared/mail/useNewMailNotifications.d.ts +35 -0
  351. package/dist/apps/shared/mail/useNewMailNotifications.js +130 -0
  352. package/dist/apps/shared/mail/useUnreadTitle.d.ts +18 -0
  353. package/dist/apps/shared/mail/useUnreadTitle.js +31 -0
  354. package/dist/apps/shared/navigation/AppRouter.d.ts +52 -0
  355. package/dist/apps/shared/navigation/AppRouter.js +242 -0
  356. package/dist/apps/shared/navigation/appHrefs.d.ts +14 -0
  357. package/dist/apps/shared/navigation/appHrefs.js +20 -0
  358. package/dist/apps/shared/navigation/frameContext.d.ts +19 -0
  359. package/dist/apps/shared/navigation/frameContext.js +24 -0
  360. package/dist/apps/shared/navigation/idle.d.ts +14 -0
  361. package/dist/apps/shared/navigation/idle.js +43 -0
  362. package/dist/apps/shared/navigation/routerContext.d.ts +37 -0
  363. package/dist/apps/shared/navigation/routerContext.js +56 -0
  364. package/dist/apps/shared/navigation/routes.d.ts +32 -0
  365. package/dist/apps/shared/navigation/routes.js +37 -0
  366. package/dist/apps/shared/notifications/NotificationCenter.d.ts +19 -0
  367. package/dist/apps/shared/notifications/NotificationCenter.js +90 -0
  368. package/dist/apps/shared/notifications/NotificationHistoryDialog.d.ts +10 -0
  369. package/dist/apps/shared/notifications/NotificationHistoryDialog.js +36 -0
  370. package/dist/apps/shared/notifications/apiErrors.d.ts +19 -0
  371. package/dist/apps/shared/notifications/apiErrors.js +86 -0
  372. package/dist/apps/shared/notifications/headerOffset.d.ts +8 -0
  373. package/dist/apps/shared/notifications/headerOffset.js +33 -0
  374. package/dist/apps/shared/notifications/pushStatus.d.ts +9 -0
  375. package/dist/apps/shared/notifications/pushStatus.js +54 -0
  376. package/dist/apps/shared/notifications/store.d.ts +136 -0
  377. package/dist/apps/shared/notifications/store.js +416 -0
  378. package/dist/apps/shared/notifications/systemErrors.d.ts +9 -0
  379. package/dist/apps/shared/notifications/systemErrors.js +58 -0
  380. package/dist/apps/shared/notifications/useNotifications.d.ts +17 -0
  381. package/dist/apps/shared/notifications/useNotifications.js +18 -0
  382. package/dist/apps/shared/search/LocalIndexLifecycle.js +17 -3
  383. package/dist/apps/shared/signing/enrollmentStorage.d.ts +10 -0
  384. package/dist/apps/shared/signing/enrollmentStorage.js +33 -0
  385. package/dist/apps/shared/signing/enrollmentTracker.d.ts +73 -0
  386. package/dist/apps/shared/signing/enrollmentTracker.js +307 -0
  387. package/dist/apps/shared/signing/enrollmentView.d.ts +57 -0
  388. package/dist/apps/shared/signing/enrollmentView.js +214 -0
  389. package/dist/apps/shared/signing/signingInfo.d.ts +11 -0
  390. package/dist/apps/shared/signing/signingInfo.js +48 -0
  391. package/dist/apps/shared/signing/useNow.d.ts +2 -0
  392. package/dist/apps/shared/signing/useNow.js +18 -0
  393. package/dist/apps/shared/signing/useSigningEnrollmentWatcher.d.ts +16 -0
  394. package/dist/apps/shared/signing/useSigningEnrollmentWatcher.js +87 -0
  395. package/dist/apps/shared/styles/app.css +108 -10
  396. package/dist/apps/www/_layout.d.ts +5 -1
  397. package/dist/apps/www/_layout.js +3 -2
  398. package/dist/apps/www/_routedPage.d.ts +12 -0
  399. package/dist/apps/www/_routedPage.js +19 -0
  400. package/dist/apps/www/_routes.d.ts +11 -0
  401. package/dist/apps/www/_routes.js +30 -0
  402. package/dist/apps/www/calendar/index.d.ts +2 -2
  403. package/dist/apps/www/calendar/index.js +41 -11
  404. package/dist/apps/www/contacts/[uid].d.ts +3 -9
  405. package/dist/apps/www/contacts/[uid].js +11 -9
  406. package/dist/apps/www/contacts/index.d.ts +2 -2
  407. package/dist/apps/www/contacts/index.js +30 -24
  408. package/dist/apps/www/index.d.ts +2 -2
  409. package/dist/apps/www/index.js +332 -48
  410. package/dist/apps/www/messages/[uid].d.ts +3 -7
  411. package/dist/apps/www/messages/[uid].js +10 -5
  412. package/dist/apps/www/settings/appearance/index.d.ts +4 -0
  413. package/dist/apps/www/settings/appearance/index.js +13 -0
  414. package/dist/apps/www/settings/auto-reply/index.d.ts +2 -2
  415. package/dist/apps/www/settings/auto-reply/index.js +6 -7
  416. package/dist/apps/www/settings/encryption/index.d.ts +2 -2
  417. package/dist/apps/www/settings/encryption/index.js +106 -96
  418. package/dist/apps/www/settings/filters/[uid].d.ts +2 -2
  419. package/dist/apps/www/settings/filters/[uid].js +6 -2
  420. package/dist/apps/www/settings/filters/index.d.ts +2 -2
  421. package/dist/apps/www/settings/filters/index.js +3 -1
  422. package/dist/apps/www/settings/filters/new/index.d.ts +2 -2
  423. package/dist/apps/www/settings/filters/new/index.js +9 -3
  424. package/dist/apps/www/settings/labels/index.d.ts +2 -2
  425. package/dist/apps/www/settings/labels/index.js +3 -1
  426. package/dist/apps/www/settings/privacy/index.d.ts +2 -2
  427. package/dist/apps/www/settings/privacy/index.js +8 -9
  428. package/dist/apps/www/settings/read-receipts/index.d.ts +2 -2
  429. package/dist/apps/www/settings/read-receipts/index.js +6 -7
  430. package/dist/apps/www/settings/sharing/index.d.ts +2 -2
  431. package/dist/apps/www/settings/sharing/index.js +22 -34
  432. package/dist/apps/www/settings/signatures/[uid].d.ts +2 -2
  433. package/dist/apps/www/settings/signatures/[uid].js +6 -2
  434. package/dist/apps/www/settings/signatures/index.d.ts +2 -2
  435. package/dist/apps/www/settings/signatures/index.js +3 -1
  436. package/dist/apps/www/settings/signatures/new/index.d.ts +2 -2
  437. package/dist/apps/www/settings/signatures/new/index.js +9 -4
  438. package/dist/apps/www/tasks/index.d.ts +2 -2
  439. package/dist/apps/www/tasks/index.js +22 -16
  440. package/package.json +2 -2
  441. package/apps/shared/components/mail/compose/SendFailureAlert.tsx +0 -48
  442. package/dist/apps/shared/components/mail/compose/SendFailureAlert.d.ts +0 -14
  443. package/dist/apps/shared/components/mail/compose/SendFailureAlert.js +0 -11
@@ -3,7 +3,9 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
3
  // Copyright (C) 2026 Jean-Philippe Steinmetz
4
4
  // SPDX-License-Identifier: MPL-2.0
5
5
  ///////////////////////////////////////////////////////////////////////////////
6
- import { useEffect, useMemo, useState } from "react";
6
+ import { routedPage } from "../_routedPage.js";
7
+ import { useNavigate } from "../../shared/navigation/AppRouter.js";
8
+ import { useEffect, useMemo, useRef, useState } from "react";
7
9
  import { ApiRequestError } from "@rapidmx/react-shared/util/api.js";
8
10
  import { createContact, deleteContact, listContacts, listDeletedContacts, setContactFavorite, updateContact, } from "@rapidmx/react-shared/contacts/contactsApi.js";
9
11
  import { contactsToVCardFile, contactToVCard, parseVCards } from "@rapidmx/react-shared/contacts/vcard.js";
@@ -22,8 +24,11 @@ import Button from "@rapidmx/react-shared/components/buttons/Button.js";
22
24
  import Modal from "@rapidmx/react-shared/components/overlays/Modal.js";
23
25
  import { LIST_PAGE_SIZE, MAX_LIST_PAGES, listAllPages } from "../../shared/mail/listAllPages.js";
24
26
  import { clearPinnedSignerCache } from "../../shared/components/mail/pinnedSigners.js";
27
+ import { SHORTCUTS } from "../../shared/keyboard/keymap.js";
28
+ import { useShortcut } from "../../shared/keyboard/useShortcut.js";
29
+ import { notifyApiError } from "../../shared/notifications/apiErrors.js";
25
30
  const INPUT_CLASS = "w-full text-sm py-2 px-3 border border-border rounded-sm bg-surface text-text focus:outline-none focus:border-primary";
26
- export default function ContactsPage(props) {
31
+ function ContactsPage(props) {
27
32
  return (_jsx(ContactsShell, { ...props, children: _jsx(ContactsContent, { userUid: props.userUid }) }));
28
33
  }
29
34
  /** Shown in the Deleted view when the server answered `?deleted=true` with live contacts (see `canViewDeleted`). */
@@ -51,6 +56,7 @@ function ContactsContent({ userUid }) {
51
56
  const writableMailboxes = useWritableMailboxes(mailboxes, userUid, mailboxUid);
52
57
  const { openCompose } = useCompose();
53
58
  const isMobile = useIsMobile();
59
+ const navigate = useNavigate();
54
60
  const [contacts, setContacts] = useState([]);
55
61
  const [deletedContacts, setDeletedContacts] = useState([]);
56
62
  const [deletedLoading, setDeletedLoading] = useState(false);
@@ -70,10 +76,9 @@ function ContactsContent({ userUid }) {
70
76
  // Set after a contact is created in a different mailbox than the one this list shows.
71
77
  const [savedElsewhere, setSavedElsewhere] = useState(null);
72
78
  const [confirmingBulkDelete, setConfirmingBulkDelete] = useState(false);
73
- /** Returns a promise so bulk actions (below) can wait for the refreshed list before re-asserting their
74
- * own error message — this always clears `error` first (a legitimate reset for a fresh fetch attempt),
75
- * which would otherwise silently wipe out a bulk action's own just-set failure message before the user
76
- * ever saw it, since every bulk handler calls this right after its own error-setting loop. */
79
+ /** Returns a promise so bulk actions (below) can wait for the refreshed list. `error` is only this list's own
80
+ * load failure (cleared first, for a fresh fetch attempt); a failed action is a pop-up instead
81
+ * (`notifyApiError()`), which a reload doesn't touch. */
77
82
  function reload() {
78
83
  if (!folderUid) {
79
84
  setContacts([]);
@@ -208,7 +213,7 @@ function ContactsContent({ userUid }) {
208
213
  }
209
214
  function handleSelectRow(contact) {
210
215
  if (isMobile) {
211
- window.location.href = `/contacts/${encodeURIComponent(contact.uid)}`;
216
+ navigate(`/contacts/${encodeURIComponent(contact.uid)}`);
212
217
  return;
213
218
  }
214
219
  setSelectedUid(contact.uid);
@@ -218,6 +223,13 @@ function ContactsContent({ userUid }) {
218
223
  setSelectedUid(null);
219
224
  setMode("new");
220
225
  }
226
+ // Keyboard shortcuts - the toolbar's New contact and the search box. (A dialog open silences them.)
227
+ const searchInputRef = useRef(null);
228
+ useShortcut(SHORTCUTS.contacts.create, handleNew);
229
+ useShortcut(SHORTCUTS.contacts.search, () => {
230
+ searchInputRef.current?.focus();
231
+ searchInputRef.current?.select();
232
+ });
221
233
  function handleSaved(contact) {
222
234
  setMode("view");
223
235
  if (contact.mailboxUid !== mailboxUid) {
@@ -243,24 +255,23 @@ function ContactsContent({ userUid }) {
243
255
  void reload();
244
256
  }
245
257
  catch (err) {
246
- setError(err instanceof ApiRequestError ? err.message : "Could not delete this contact.");
258
+ notifyApiError(err, "Couldn't delete the contact");
247
259
  }
248
260
  }
261
+ // The bulk handlers below try every contact and report each failure: the same failure repeated is one pop-up with a count.
249
262
  async function handleBulkDelete() {
250
263
  setConfirmingBulkDelete(false);
251
- let bulkError = null;
252
264
  for (const contact of checkedContacts) {
253
265
  try {
254
266
  await deleteContact(contact.uid, contact.version);
255
267
  }
256
268
  catch (err) {
257
- bulkError = err instanceof ApiRequestError ? err.message : "Could not delete one or more contacts.";
269
+ notifyApiError(err, "Couldn't delete some of the contacts");
258
270
  }
259
271
  }
260
272
  clearPinnedSignerCache();
261
273
  setCheckedUids(new Set());
262
274
  await reload();
263
- setError(bulkError);
264
275
  }
265
276
  // `ContactsToolbar`'s Edit button — the only caller — is itself `disabled` unless exactly one contact
266
277
  // is checked, so `checkedContacts[0]` is guaranteed to exist whenever this actually runs; no length
@@ -278,25 +289,22 @@ function ContactsContent({ userUid }) {
278
289
  }
279
290
  async function handleToggleFavorite() {
280
291
  const allFavorited = checkedContacts.every((c) => c.favorite);
281
- let bulkError = null;
282
292
  for (const contact of checkedContacts) {
283
293
  try {
284
294
  await setContactFavorite(contact, !allFavorited);
285
295
  }
286
296
  catch (err) {
287
- bulkError = err instanceof ApiRequestError ? err.message : "Could not update one or more contacts.";
297
+ notifyApiError(err, "Couldn't update some of the contacts");
288
298
  }
289
299
  }
290
300
  clearPinnedSignerCache();
291
301
  await reload();
292
- setError(bulkError);
293
302
  }
294
303
  async function handleAddCategory() {
295
304
  const category = window.prompt("Category name");
296
305
  if (!category?.trim()) {
297
306
  return;
298
307
  }
299
- let bulkError = null;
300
308
  for (const contact of checkedContacts) {
301
309
  const categories = Array.from(new Set([...(contact.categories ?? []), category.trim()]));
302
310
  try {
@@ -305,12 +313,11 @@ function ContactsContent({ userUid }) {
305
313
  await updateContact({ uid: contact.uid, version: contact.version, categories });
306
314
  }
307
315
  catch (err) {
308
- bulkError = err instanceof ApiRequestError ? err.message : "Could not update one or more contacts.";
316
+ notifyApiError(err, "Couldn't update some of the contacts");
309
317
  }
310
318
  }
311
319
  clearPinnedSignerCache();
312
320
  await reload();
313
- setError(bulkError);
314
321
  }
315
322
  function handleExportVCard() {
316
323
  downloadTextFile(checkedContacts.length === 1 ? `${checkedContacts[0].displayName}.vcf` : "contacts.vcf", checkedContacts.length === 1 ? contactToVCard(checkedContacts[0]) : contactsToVCardFile(checkedContacts));
@@ -321,21 +328,20 @@ function ContactsContent({ userUid }) {
321
328
  }
322
329
  const text = await file.text();
323
330
  const parsed = parseVCards(text);
324
- let bulkError = null;
325
331
  for (const input of parsed) {
326
332
  try {
327
333
  await createContact({ mailboxUid, folderUid, ...input });
328
334
  }
329
335
  catch (err) {
330
- bulkError = err instanceof ApiRequestError ? err.message : "Could not import one or more contacts.";
336
+ notifyApiError(err, "Couldn't import some of the contacts");
331
337
  }
332
338
  }
333
339
  clearPinnedSignerCache();
334
340
  await reload();
335
- setError(bulkError);
336
341
  }
337
- return (_jsxs("div", { className: "flex-1 flex min-h-0", children: [_jsx(ContactsSidebar, { mailboxUid: mailboxUid, contacts: contacts, active: view, onSelect: handleSelectView, showDeleted: canViewDeleted }), _jsxs("div", { className: [
338
- "w-full md:w-96 shrink-0 md:border-r border-border md:flex flex-col min-h-0",
339
- mode === "new" ? "hidden md:flex" : "flex",
340
- ].join(" "), children: [_jsx(ContactsToolbar, { selectedCount: checkedContacts.length, allSelectedFavorited: checkedContacts.length > 0 && checkedContacts.every((c) => c.favorite), onNewContact: handleNew, onEdit: handleToolbarEdit, onDelete: () => setConfirmingBulkDelete(true), onEmail: handleEmail, onToggleFavorite: handleToggleFavorite, onAddCategory: handleAddCategory, onExportVCard: handleExportVCard, onImportFile: handleImportFile }), _jsx("div", { className: "p-3 border-b border-border", children: _jsx("input", { type: "search", value: query, onChange: (e) => setQuery(e.target.value), placeholder: "Search contacts", "aria-label": "Search contacts", className: INPUT_CLASS }) }), error && (_jsx("div", { className: "p-3", children: _jsx(Alert, { children: error }) })), (isDeletedView ? deletedTruncated : truncated) && (_jsx("div", { className: "p-3", children: _jsxs(Alert, { children: ["This folder has more contacts than can be shown at once - only the first ", LIST_PAGE_SIZE * MAX_LIST_PAGES, " are listed."] }) })), deletedError && isDeletedView && (_jsx("div", { className: "p-3", children: _jsx(Alert, { children: deletedError }) })), (isDeletedView ? deletedLoading : loading) ? (_jsx("p", { className: "p-4 text-sm text-text-muted", children: "Loading\u2026" })) : sorted.length === 0 ? (_jsx("p", { className: "p-4 text-sm text-text-muted", children: "No contacts found." })) : (_jsx("div", { className: "flex-1 overflow-auto", children: _jsxs("table", { className: "w-full text-sm", children: [_jsx("thead", { children: _jsxs("tr", { className: "border-b border-border text-left", children: [!isDeletedView && (_jsx("th", { className: "w-8 px-3 py-2", children: _jsx("input", { type: "checkbox", "aria-label": "Select all contacts", checked: allChecked, onChange: toggleCheckAll }) })), _jsx("th", { className: "px-3 py-2", children: _jsxs("button", { type: "button", onClick: () => handleSort("name"), className: "text-xs font-bold uppercase tracking-wide text-text-muted", children: ["Name", sortColumn === "name" ? (sortDesc ? " ▾" : " ▴") : ""] }) }), _jsx("th", { className: "px-3 py-2", children: _jsxs("button", { type: "button", onClick: () => handleSort("info"), className: "text-xs font-bold uppercase tracking-wide text-text-muted", children: ["Contact info", sortColumn === "info" ? (sortDesc ? " ▾" : " ▴") : ""] }) })] }) }), _jsx("tbody", { children: sorted.map((contact) => (_jsxs("tr", { className: ["border-b border-border", contact.uid === selectedUid ? "bg-primary/10" : "hover:bg-surface-alt"].join(" "), children: [!isDeletedView && (_jsx("td", { className: "px-3 py-2", children: _jsx("input", { type: "checkbox", "aria-label": `Select ${contact.displayName}`, checked: checkedUids.has(contact.uid), onChange: () => toggleChecked(contact.uid) }) })), _jsx("td", { className: "px-3 py-2", children: _jsxs("button", { type: "button", onClick: () => handleSelectRow(contact), className: "flex items-center gap-2 text-left", children: [_jsx(ContactAvatar, { displayName: contact.displayName, size: 28 }), _jsxs("span", { className: "truncate font-medium", children: [contact.displayName, contact.favorite && _jsx("span", { "aria-label": "Favorite", children: " \u2605" })] })] }) }), _jsx("td", { className: "px-3 py-2 text-text-muted truncate", children: primaryInfo(contact) })] }, contact.uid))) })] }) }))] }), _jsxs("div", { className: ["flex-1 min-w-0 overflow-y-auto p-6 md:block", mode === "new" ? "block" : "hidden"].join(" "), children: [savedElsewhere && mode !== "new" && (_jsxs("p", { role: "status", className: "mb-4 text-sm py-2 px-3 rounded-sm bg-surface-alt text-text", children: [savedElsewhere.displayName, " was added to", " ", mailboxes.find((mb) => mb.uid === savedElsewhere.mailboxUid)?.displayName ?? "another mailbox", ".", " ", _jsx("a", { href: `/contacts?mailboxUid=${encodeURIComponent(savedElsewhere.mailboxUid)}`, className: "font-medium text-primary-dark hover:underline", children: "View that mailbox\u2019s contacts" })] })), mode === "new" && mailboxUid && folderUid ? (_jsx(ContactForm, { mailboxUid: mailboxUid, folderUid: folderUid, mailboxes: writableMailboxes, onSaved: handleSaved, onCancel: handleCancel })) : mode === "edit" && selected ? (_jsx(ContactForm, { contact: selected, onSaved: handleSaved, onCancel: handleCancel })) : selected ? (_jsx(ContactDetailPane, { contact: selected, onEdit: () => setMode("edit"), onDelete: () => handleDelete(selected), onKeysChanged: () => void reload(), canResolveKeys: ownsMailbox || delegateCanUpdate })) : (_jsx("p", { className: "text-sm text-text-muted", children: "Select a contact, or create a new one." }))] }), _jsxs(Modal, { open: confirmingBulkDelete, onClose: () => setConfirmingBulkDelete(false), title: "Delete contacts", children: [_jsxs("p", { className: "text-sm mb-5", children: ["Delete ", checkedContacts.length, " selected ", checkedContacts.length === 1 ? "contact" : "contacts", "? They move to Deleted contacts."] }), _jsxs("div", { className: "flex gap-3 justify-end", children: [_jsx(Button, { type: "button", variant: "secondary", className: "!w-auto", onClick: () => setConfirmingBulkDelete(false), children: "Cancel" }), _jsx(Button, { type: "button", className: "!w-auto !bg-none !bg-danger !border-danger hover:!bg-danger", onClick: handleBulkDelete, children: "Delete" })] })] })] }));
342
+ return (_jsxs("div", { className: "flex-1 min-w-0 min-h-0 flex flex-col lg:flex-row md:flex-none md:h-[calc(100dvh_-_var(--rr-header-h,4rem))] md:overflow-hidden", children: [_jsx(ContactsSidebar, { mailboxUid: mailboxUid, contacts: contacts, active: view, onSelect: handleSelectView, showDeleted: canViewDeleted }), _jsxs("div", { className: "flex-1 min-w-0 min-h-0 flex", children: [_jsxs("div", { className: [
343
+ "w-full md:w-[clamp(16rem,32vw,26rem)] min-w-0 md:shrink-0 md:border-r border-border md:flex flex-col min-h-0",
344
+ mode === "new" ? "hidden md:flex" : "flex",
345
+ ].join(" "), children: [_jsx(ContactsToolbar, { selectedCount: checkedContacts.length, allSelectedFavorited: checkedContacts.length > 0 && checkedContacts.every((c) => c.favorite), onNewContact: handleNew, onEdit: handleToolbarEdit, onDelete: () => setConfirmingBulkDelete(true), onEmail: handleEmail, onToggleFavorite: handleToggleFavorite, onAddCategory: handleAddCategory, onExportVCard: handleExportVCard, onImportFile: handleImportFile, shortcuts: true }), _jsx("div", { className: "p-3 border-b border-border", children: _jsx("input", { ref: searchInputRef, type: "search", value: query, onChange: (e) => setQuery(e.target.value), placeholder: "Search contacts", "aria-label": "Search contacts", className: INPUT_CLASS }) }), error && (_jsx("div", { className: "p-3", children: _jsx(Alert, { children: error }) })), (isDeletedView ? deletedTruncated : truncated) && (_jsx("div", { className: "p-3", children: _jsxs(Alert, { children: ["This folder has more contacts than can be shown at once - only the first ", LIST_PAGE_SIZE * MAX_LIST_PAGES, " are listed."] }) })), deletedError && isDeletedView && (_jsx("div", { className: "p-3", children: _jsx(Alert, { children: deletedError }) })), (isDeletedView ? deletedLoading : loading) ? (_jsx("p", { className: "p-4 text-sm text-text-muted", children: "Loading\u2026" })) : sorted.length === 0 ? (_jsx("p", { className: "p-4 text-sm text-text-muted", children: "No contacts found." })) : (_jsx("div", { className: "flex-1 min-h-0 overflow-auto", children: _jsxs("table", { className: "w-full table-fixed text-sm", children: [_jsx("thead", { children: _jsxs("tr", { className: "border-b border-border text-left", children: [!isDeletedView && (_jsx("th", { className: "w-10 px-3 py-2", children: _jsx("input", { type: "checkbox", "aria-label": "Select all contacts", checked: allChecked, onChange: toggleCheckAll }) })), _jsx("th", { className: "w-[58%] px-3 py-2", children: _jsxs("button", { type: "button", onClick: () => handleSort("name"), className: "block max-w-full truncate text-xs font-bold uppercase tracking-wide text-text-muted", children: ["Name", sortColumn === "name" ? (sortDesc ? " ▾" : " ▴") : ""] }) }), _jsx("th", { className: "px-3 py-2", children: _jsxs("button", { type: "button", onClick: () => handleSort("info"), className: "block max-w-full truncate text-xs font-bold uppercase tracking-wide text-text-muted", children: ["Contact info", sortColumn === "info" ? (sortDesc ? " ▾" : " ▴") : ""] }) })] }) }), _jsx("tbody", { children: sorted.map((contact) => (_jsxs("tr", { className: ["border-b border-border", contact.uid === selectedUid ? "bg-primary/10" : "hover:bg-surface-alt"].join(" "), children: [!isDeletedView && (_jsx("td", { className: "px-3 py-2", children: _jsx("input", { type: "checkbox", "aria-label": `Select ${contact.displayName}`, checked: checkedUids.has(contact.uid), onChange: () => toggleChecked(contact.uid) }) })), _jsx("td", { className: "px-3 py-2", children: _jsxs("button", { type: "button", onClick: () => handleSelectRow(contact), className: "flex w-full min-w-0 items-center gap-2 text-left", children: [_jsx(ContactAvatar, { displayName: contact.displayName, size: 28 }), _jsxs("span", { className: "min-w-0 truncate font-medium", children: [contact.displayName, contact.favorite && _jsx("span", { "aria-label": "Favorite", children: " \u2605" })] })] }) }), _jsx("td", { className: "max-w-0 truncate px-3 py-2 text-text-muted", children: primaryInfo(contact) })] }, contact.uid))) })] }) }))] }), _jsxs("div", { className: ["flex-1 min-w-0 min-h-0 flex-col md:flex", mode === "new" ? "flex" : "hidden"].join(" "), children: [savedElsewhere && mode !== "new" && (_jsxs("p", { role: "status", className: "m-6 mb-0 text-sm py-2 px-3 rounded-sm bg-surface-alt text-text", children: [savedElsewhere.displayName, " was added to", " ", mailboxes.find((mb) => mb.uid === savedElsewhere.mailboxUid)?.displayName ?? "another mailbox", ".", " ", _jsx("a", { href: `/contacts?mailboxUid=${encodeURIComponent(savedElsewhere.mailboxUid)}`, className: "font-medium text-primary-dark hover:underline", children: "View that mailbox\u2019s contacts" })] })), mode === "new" && mailboxUid && folderUid ? (_jsx(ContactForm, { mailboxUid: mailboxUid, folderUid: folderUid, mailboxes: writableMailboxes, onSaved: handleSaved, onCancel: handleCancel })) : mode === "edit" && selected ? (_jsx(ContactForm, { contact: selected, onSaved: handleSaved, onCancel: handleCancel })) : selected ? (_jsx("div", { className: "min-h-0 flex-1 overflow-y-auto p-6", children: _jsx(ContactDetailPane, { contact: selected, onEdit: () => setMode("edit"), onDelete: () => handleDelete(selected), onKeysChanged: () => void reload(), canResolveKeys: ownsMailbox || delegateCanUpdate }) })) : (_jsx("div", { className: "flex flex-1 items-center justify-center p-6 text-center", children: _jsx("p", { className: "text-sm text-text-muted", children: "Select a contact, or create a new one." }) }))] })] }), _jsxs(Modal, { open: confirmingBulkDelete, onClose: () => setConfirmingBulkDelete(false), title: "Delete contacts", children: [_jsxs("p", { className: "text-sm mb-5", children: ["Delete ", checkedContacts.length, " selected ", checkedContacts.length === 1 ? "contact" : "contacts", "? They move to Deleted contacts."] }), _jsxs("div", { className: "flex gap-3 justify-end", children: [_jsx(Button, { type: "button", variant: "secondary", className: "!w-auto", onClick: () => setConfirmingBulkDelete(false), children: "Cancel" }), _jsx(Button, { type: "button", className: "!w-auto !bg-none !bg-danger !border-danger hover:!bg-danger", onClick: handleBulkDelete, children: "Delete" })] })] })] }));
341
346
  }
347
+ export default routedPage("/contacts", ContactsPage);
@@ -1,3 +1,3 @@
1
- import React from "react";
2
1
  import { MailShellProps } from "../shared/components/mail/layout/MailShell.js";
3
- export default function InboxPage(props: MailShellProps): React.JSX.Element;
2
+ declare const _default: import("../shared/navigation/AppRouter.js").RoutedPageComponent<MailShellProps>;
3
+ export default _default;