@aglyn/plugins-crm 1.0.0-beta.143

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 (669) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +7 -0
  3. package/package.json +57 -0
  4. package/src/index.d.ts +21 -0
  5. package/src/index.js +29 -0
  6. package/src/index.js.map +1 -0
  7. package/src/lib/components/activity-list.d.ts +98 -0
  8. package/src/lib/components/activity-list.js +321 -0
  9. package/src/lib/components/activity-list.js.map +1 -0
  10. package/src/lib/components/activity-queries.d.ts +117 -0
  11. package/src/lib/components/activity-queries.js +198 -0
  12. package/src/lib/components/activity-queries.js.map +1 -0
  13. package/src/lib/components/add-to-list-button.d.ts +25 -0
  14. package/src/lib/components/add-to-list-button.js +64 -0
  15. package/src/lib/components/add-to-list-button.js.map +1 -0
  16. package/src/lib/components/add-to-list-dialog.d.ts +24 -0
  17. package/src/lib/components/add-to-list-dialog.js +327 -0
  18. package/src/lib/components/add-to-list-dialog.js.map +1 -0
  19. package/src/lib/components/assignment-rule-drawer.d.ts +43 -0
  20. package/src/lib/components/assignment-rule-drawer.js +293 -0
  21. package/src/lib/components/assignment-rule-drawer.js.map +1 -0
  22. package/src/lib/components/companies-bulk-bar.d.ts +29 -0
  23. package/src/lib/components/companies-bulk-bar.js +274 -0
  24. package/src/lib/components/companies-bulk-bar.js.map +1 -0
  25. package/src/lib/components/companies-section.d.ts +54 -0
  26. package/src/lib/components/companies-section.js +522 -0
  27. package/src/lib/components/companies-section.js.map +1 -0
  28. package/src/lib/components/company-contacts-card.d.ts +49 -0
  29. package/src/lib/components/company-contacts-card.js +435 -0
  30. package/src/lib/components/company-contacts-card.js.map +1 -0
  31. package/src/lib/components/company-deals-card.d.ts +20 -0
  32. package/src/lib/components/company-deals-card.js +38 -0
  33. package/src/lib/components/company-deals-card.js.map +1 -0
  34. package/src/lib/components/company-detail-page.d.ts +20 -0
  35. package/src/lib/components/company-detail-page.js +165 -0
  36. package/src/lib/components/company-detail-page.js.map +1 -0
  37. package/src/lib/components/company-edit-drawer.d.ts +65 -0
  38. package/src/lib/components/company-edit-drawer.js +433 -0
  39. package/src/lib/components/company-edit-drawer.js.map +1 -0
  40. package/src/lib/components/company-import-drawer.d.ts +42 -0
  41. package/src/lib/components/company-import-drawer.js +99 -0
  42. package/src/lib/components/company-import-drawer.js.map +1 -0
  43. package/src/lib/components/company-picker.d.ts +127 -0
  44. package/src/lib/components/company-picker.js +323 -0
  45. package/src/lib/components/company-picker.js.map +1 -0
  46. package/src/lib/components/company-properties-card.d.ts +47 -0
  47. package/src/lib/components/company-properties-card.js +289 -0
  48. package/src/lib/components/company-properties-card.js.map +1 -0
  49. package/src/lib/components/contact-address-fields.d.ts +29 -0
  50. package/src/lib/components/contact-address-fields.js +149 -0
  51. package/src/lib/components/contact-address-fields.js.map +1 -0
  52. package/src/lib/components/contact-associations-card.d.ts +72 -0
  53. package/src/lib/components/contact-associations-card.js +296 -0
  54. package/src/lib/components/contact-associations-card.js.map +1 -0
  55. package/src/lib/components/contact-custom-columns.d.ts +38 -0
  56. package/src/lib/components/contact-custom-columns.js +102 -0
  57. package/src/lib/components/contact-custom-columns.js.map +1 -0
  58. package/src/lib/components/contact-custom-fields-card.d.ts +39 -0
  59. package/src/lib/components/contact-custom-fields-card.js +204 -0
  60. package/src/lib/components/contact-custom-fields-card.js.map +1 -0
  61. package/src/lib/components/contact-deals-card.d.ts +20 -0
  62. package/src/lib/components/contact-deals-card.js +38 -0
  63. package/src/lib/components/contact-deals-card.js.map +1 -0
  64. package/src/lib/components/contact-detail-page.d.ts +46 -0
  65. package/src/lib/components/contact-detail-page.js +535 -0
  66. package/src/lib/components/contact-detail-page.js.map +1 -0
  67. package/src/lib/components/contact-duplicates-card.d.ts +42 -0
  68. package/src/lib/components/contact-duplicates-card.js +167 -0
  69. package/src/lib/components/contact-duplicates-card.js.map +1 -0
  70. package/src/lib/components/contact-field-drawer.d.ts +64 -0
  71. package/src/lib/components/contact-field-drawer.js +251 -0
  72. package/src/lib/components/contact-field-drawer.js.map +1 -0
  73. package/src/lib/components/contact-import-drawer.d.ts +46 -0
  74. package/src/lib/components/contact-import-drawer.js +149 -0
  75. package/src/lib/components/contact-import-drawer.js.map +1 -0
  76. package/src/lib/components/contact-known-by-card.d.ts +39 -0
  77. package/src/lib/components/contact-known-by-card.js +142 -0
  78. package/src/lib/components/contact-known-by-card.js.map +1 -0
  79. package/src/lib/components/contact-list-columns.d.ts +53 -0
  80. package/src/lib/components/contact-list-columns.js +288 -0
  81. package/src/lib/components/contact-list-columns.js.map +1 -0
  82. package/src/lib/components/contact-merge-dialog.d.ts +79 -0
  83. package/src/lib/components/contact-merge-dialog.js +405 -0
  84. package/src/lib/components/contact-merge-dialog.js.map +1 -0
  85. package/src/lib/components/contact-properties-card.d.ts +89 -0
  86. package/src/lib/components/contact-properties-card.js +492 -0
  87. package/src/lib/components/contact-properties-card.js.map +1 -0
  88. package/src/lib/components/contact-timeline-card.d.ts +68 -0
  89. package/src/lib/components/contact-timeline-card.js +435 -0
  90. package/src/lib/components/contact-timeline-card.js.map +1 -0
  91. package/src/lib/components/contacts-bulk-bar.d.ts +91 -0
  92. package/src/lib/components/contacts-bulk-bar.js +493 -0
  93. package/src/lib/components/contacts-bulk-bar.js.map +1 -0
  94. package/src/lib/components/contacts-section.d.ts +26 -0
  95. package/src/lib/components/contacts-section.js +1025 -0
  96. package/src/lib/components/contacts-section.js.map +1 -0
  97. package/src/lib/components/copy-capture-address-button.d.ts +33 -0
  98. package/src/lib/components/copy-capture-address-button.js +60 -0
  99. package/src/lib/components/copy-capture-address-button.js.map +1 -0
  100. package/src/lib/components/crm-attribution-zone.d.ts +38 -0
  101. package/src/lib/components/crm-attribution-zone.js +36 -0
  102. package/src/lib/components/crm-attribution-zone.js.map +1 -0
  103. package/src/lib/components/crm-booking-zone.d.ts +61 -0
  104. package/src/lib/components/crm-booking-zone.js +50 -0
  105. package/src/lib/components/crm-booking-zone.js.map +1 -0
  106. package/src/lib/components/crm-bulk-bar-frame.d.ts +47 -0
  107. package/src/lib/components/crm-bulk-bar-frame.js +137 -0
  108. package/src/lib/components/crm-bulk-bar-frame.js.map +1 -0
  109. package/src/lib/components/crm-call-actions.d.ts +65 -0
  110. package/src/lib/components/crm-call-actions.js +110 -0
  111. package/src/lib/components/crm-call-actions.js.map +1 -0
  112. package/src/lib/components/crm-column-menu.d.ts +21 -0
  113. package/src/lib/components/crm-column-menu.js +103 -0
  114. package/src/lib/components/crm-column-menu.js.map +1 -0
  115. package/src/lib/components/crm-console-page.d.ts +19 -0
  116. package/src/lib/components/crm-console-page.js +151 -0
  117. package/src/lib/components/crm-console-page.js.map +1 -0
  118. package/src/lib/components/crm-console-sections.d.ts +52 -0
  119. package/src/lib/components/crm-console-sections.js +83 -0
  120. package/src/lib/components/crm-console-sections.js.map +1 -0
  121. package/src/lib/components/crm-custom-field-control.d.ts +26 -0
  122. package/src/lib/components/crm-custom-field-control.js +131 -0
  123. package/src/lib/components/crm-custom-field-control.js.map +1 -0
  124. package/src/lib/components/crm-email-template-tools.d.ts +69 -0
  125. package/src/lib/components/crm-email-template-tools.js +240 -0
  126. package/src/lib/components/crm-email-template-tools.js.map +1 -0
  127. package/src/lib/components/crm-export-all-button.d.ts +39 -0
  128. package/src/lib/components/crm-export-all-button.js +98 -0
  129. package/src/lib/components/crm-export-all-button.js.map +1 -0
  130. package/src/lib/components/crm-filter-bar.d.ts +53 -0
  131. package/src/lib/components/crm-filter-bar.js +294 -0
  132. package/src/lib/components/crm-filter-bar.js.map +1 -0
  133. package/src/lib/components/crm-glance-card.d.ts +54 -0
  134. package/src/lib/components/crm-glance-card.js +219 -0
  135. package/src/lib/components/crm-glance-card.js.map +1 -0
  136. package/src/lib/components/crm-next-activity-column.d.ts +35 -0
  137. package/src/lib/components/crm-next-activity-column.js +100 -0
  138. package/src/lib/components/crm-next-activity-column.js.map +1 -0
  139. package/src/lib/components/crm-record-header.d.ts +97 -0
  140. package/src/lib/components/crm-record-header.js +160 -0
  141. package/src/lib/components/crm-record-header.js.map +1 -0
  142. package/src/lib/components/crm-record-insights-zone.d.ts +50 -0
  143. package/src/lib/components/crm-record-insights-zone.js +169 -0
  144. package/src/lib/components/crm-record-insights-zone.js.map +1 -0
  145. package/src/lib/components/crm-record-picker.d.ts +42 -0
  146. package/src/lib/components/crm-record-picker.js +104 -0
  147. package/src/lib/components/crm-record-picker.js.map +1 -0
  148. package/src/lib/components/crm-send-email-button.d.ts +39 -0
  149. package/src/lib/components/crm-send-email-button.js +81 -0
  150. package/src/lib/components/crm-send-email-button.js.map +1 -0
  151. package/src/lib/components/crm-send-email-dialog.d.ts +61 -0
  152. package/src/lib/components/crm-send-email-dialog.js +851 -0
  153. package/src/lib/components/crm-send-email-dialog.js.map +1 -0
  154. package/src/lib/components/crm-site-picker.d.ts +61 -0
  155. package/src/lib/components/crm-site-picker.js +99 -0
  156. package/src/lib/components/crm-site-picker.js.map +1 -0
  157. package/src/lib/components/crm-suite-lock.d.ts +29 -0
  158. package/src/lib/components/crm-suite-lock.js +114 -0
  159. package/src/lib/components/crm-suite-lock.js.map +1 -0
  160. package/src/lib/components/crm-tasks-due-card.d.ts +42 -0
  161. package/src/lib/components/crm-tasks-due-card.js +225 -0
  162. package/src/lib/components/crm-tasks-due-card.js.map +1 -0
  163. package/src/lib/components/crm-views-control.d.ts +65 -0
  164. package/src/lib/components/crm-views-control.js +518 -0
  165. package/src/lib/components/crm-views-control.js.map +1 -0
  166. package/src/lib/components/csv-import-drawer.d.ts +132 -0
  167. package/src/lib/components/csv-import-drawer.js +746 -0
  168. package/src/lib/components/csv-import-drawer.js.map +1 -0
  169. package/src/lib/components/deal-board.d.ts +70 -0
  170. package/src/lib/components/deal-board.js +478 -0
  171. package/src/lib/components/deal-board.js.map +1 -0
  172. package/src/lib/components/deal-detail-page.d.ts +18 -0
  173. package/src/lib/components/deal-detail-page.js +323 -0
  174. package/src/lib/components/deal-detail-page.js.map +1 -0
  175. package/src/lib/components/deal-edit-drawer.d.ts +59 -0
  176. package/src/lib/components/deal-edit-drawer.js +640 -0
  177. package/src/lib/components/deal-edit-drawer.js.map +1 -0
  178. package/src/lib/components/deal-import-drawer.d.ts +24 -0
  179. package/src/lib/components/deal-import-drawer.js +83 -0
  180. package/src/lib/components/deal-import-drawer.js.map +1 -0
  181. package/src/lib/components/deal-products-card.d.ts +48 -0
  182. package/src/lib/components/deal-products-card.js +614 -0
  183. package/src/lib/components/deal-products-card.js.map +1 -0
  184. package/src/lib/components/deal-properties-card.d.ts +29 -0
  185. package/src/lib/components/deal-properties-card.js +144 -0
  186. package/src/lib/components/deal-properties-card.js.map +1 -0
  187. package/src/lib/components/deal-stage-card.d.ts +24 -0
  188. package/src/lib/components/deal-stage-card.js +199 -0
  189. package/src/lib/components/deal-stage-card.js.map +1 -0
  190. package/src/lib/components/deals-bulk-bar.d.ts +31 -0
  191. package/src/lib/components/deals-bulk-bar.js +340 -0
  192. package/src/lib/components/deals-bulk-bar.js.map +1 -0
  193. package/src/lib/components/deals-section.d.ts +49 -0
  194. package/src/lib/components/deals-section.js +767 -0
  195. package/src/lib/components/deals-section.js.map +1 -0
  196. package/src/lib/components/email-capture-card.d.ts +42 -0
  197. package/src/lib/components/email-capture-card.js +134 -0
  198. package/src/lib/components/email-capture-card.js.map +1 -0
  199. package/src/lib/components/email-template-drawer.d.ts +33 -0
  200. package/src/lib/components/email-template-drawer.js +209 -0
  201. package/src/lib/components/email-template-drawer.js.map +1 -0
  202. package/src/lib/components/email-templates-card.d.ts +33 -0
  203. package/src/lib/components/email-templates-card.js +370 -0
  204. package/src/lib/components/email-templates-card.js.map +1 -0
  205. package/src/lib/components/erase-person-action.d.ts +92 -0
  206. package/src/lib/components/erase-person-action.js +261 -0
  207. package/src/lib/components/erase-person-action.js.map +1 -0
  208. package/src/lib/components/fields-section.d.ts +37 -0
  209. package/src/lib/components/fields-section.js +641 -0
  210. package/src/lib/components/fields-section.js.map +1 -0
  211. package/src/lib/components/form-contact-fields-card.d.ts +46 -0
  212. package/src/lib/components/form-contact-fields-card.js +253 -0
  213. package/src/lib/components/form-contact-fields-card.js.map +1 -0
  214. package/src/lib/components/insert-link-at-caret.d.ts +28 -0
  215. package/src/lib/components/insert-link-at-caret.js +37 -0
  216. package/src/lib/components/insert-link-at-caret.js.map +1 -0
  217. package/src/lib/components/lead-convert-dialog.d.ts +32 -0
  218. package/src/lib/components/lead-convert-dialog.js +493 -0
  219. package/src/lib/components/lead-convert-dialog.js.map +1 -0
  220. package/src/lib/components/lead-detail-page.d.ts +16 -0
  221. package/src/lib/components/lead-detail-page.js +163 -0
  222. package/src/lib/components/lead-detail-page.js.map +1 -0
  223. package/src/lib/components/lead-history-card.d.ts +32 -0
  224. package/src/lib/components/lead-history-card.js +165 -0
  225. package/src/lib/components/lead-history-card.js.map +1 -0
  226. package/src/lib/components/lead-import-drawer.d.ts +24 -0
  227. package/src/lib/components/lead-import-drawer.js +95 -0
  228. package/src/lib/components/lead-import-drawer.js.map +1 -0
  229. package/src/lib/components/lead-owner-select.d.ts +35 -0
  230. package/src/lib/components/lead-owner-select.js +91 -0
  231. package/src/lib/components/lead-owner-select.js.map +1 -0
  232. package/src/lib/components/lead-properties-card.d.ts +61 -0
  233. package/src/lib/components/lead-properties-card.js +395 -0
  234. package/src/lib/components/lead-properties-card.js.map +1 -0
  235. package/src/lib/components/lead-status-chip.d.ts +12 -0
  236. package/src/lib/components/lead-status-chip.js +43 -0
  237. package/src/lib/components/lead-status-chip.js.map +1 -0
  238. package/src/lib/components/lead-surfaces-note.d.ts +126 -0
  239. package/src/lib/components/lead-surfaces-note.js +262 -0
  240. package/src/lib/components/lead-surfaces-note.js.map +1 -0
  241. package/src/lib/components/lead-unqualify-dialog.d.ts +24 -0
  242. package/src/lib/components/lead-unqualify-dialog.js +125 -0
  243. package/src/lib/components/lead-unqualify-dialog.js.map +1 -0
  244. package/src/lib/components/leads-bulk-bar.d.ts +58 -0
  245. package/src/lib/components/leads-bulk-bar.js +307 -0
  246. package/src/lib/components/leads-bulk-bar.js.map +1 -0
  247. package/src/lib/components/leads-section.d.ts +23 -0
  248. package/src/lib/components/leads-section.js +664 -0
  249. package/src/lib/components/leads-section.js.map +1 -0
  250. package/src/lib/components/linked-deals-card.d.ts +32 -0
  251. package/src/lib/components/linked-deals-card.js +163 -0
  252. package/src/lib/components/linked-deals-card.js.map +1 -0
  253. package/src/lib/components/log-activity-dialog.d.ts +60 -0
  254. package/src/lib/components/log-activity-dialog.js +368 -0
  255. package/src/lib/components/log-activity-dialog.js.map +1 -0
  256. package/src/lib/components/lost-reason-dialog.d.ts +26 -0
  257. package/src/lib/components/lost-reason-dialog.js +95 -0
  258. package/src/lib/components/lost-reason-dialog.js.map +1 -0
  259. package/src/lib/components/new-contact-drawer.d.ts +78 -0
  260. package/src/lib/components/new-contact-drawer.js +343 -0
  261. package/src/lib/components/new-contact-drawer.js.map +1 -0
  262. package/src/lib/components/org-lead-surfaces-note.d.ts +57 -0
  263. package/src/lib/components/org-lead-surfaces-note.js +172 -0
  264. package/src/lib/components/org-lead-surfaces-note.js.map +1 -0
  265. package/src/lib/components/owner-avatar.d.ts +18 -0
  266. package/src/lib/components/owner-avatar.js +61 -0
  267. package/src/lib/components/owner-avatar.js.map +1 -0
  268. package/src/lib/components/pipeline-stages-dialog.d.ts +43 -0
  269. package/src/lib/components/pipeline-stages-dialog.js +339 -0
  270. package/src/lib/components/pipeline-stages-dialog.js.map +1 -0
  271. package/src/lib/components/pipelines-dialog.d.ts +55 -0
  272. package/src/lib/components/pipelines-dialog.js +517 -0
  273. package/src/lib/components/pipelines-dialog.js.map +1 -0
  274. package/src/lib/components/recent-activity-feed.d.ts +39 -0
  275. package/src/lib/components/recent-activity-feed.js +103 -0
  276. package/src/lib/components/recent-activity-feed.js.map +1 -0
  277. package/src/lib/components/recipes-card.d.ts +39 -0
  278. package/src/lib/components/recipes-card.js +485 -0
  279. package/src/lib/components/recipes-card.js.map +1 -0
  280. package/src/lib/components/record-activity-card.d.ts +26 -0
  281. package/src/lib/components/record-activity-card.js +121 -0
  282. package/src/lib/components/record-activity-card.js.map +1 -0
  283. package/src/lib/components/record-files-card.d.ts +67 -0
  284. package/src/lib/components/record-files-card.js +290 -0
  285. package/src/lib/components/record-files-card.js.map +1 -0
  286. package/src/lib/components/record-tasks-card.d.ts +32 -0
  287. package/src/lib/components/record-tasks-card.js +306 -0
  288. package/src/lib/components/record-tasks-card.js.map +1 -0
  289. package/src/lib/components/reports/activity-card.d.ts +57 -0
  290. package/src/lib/components/reports/activity-card.js +281 -0
  291. package/src/lib/components/reports/activity-card.js.map +1 -0
  292. package/src/lib/components/reports/closed-deals-card.d.ts +20 -0
  293. package/src/lib/components/reports/closed-deals-card.js +194 -0
  294. package/src/lib/components/reports/closed-deals-card.js.map +1 -0
  295. package/src/lib/components/reports/contacts-mix-card.d.ts +27 -0
  296. package/src/lib/components/reports/contacts-mix-card.js +161 -0
  297. package/src/lib/components/reports/contacts-mix-card.js.map +1 -0
  298. package/src/lib/components/reports/contacts-trend-card.d.ts +31 -0
  299. package/src/lib/components/reports/contacts-trend-card.js +144 -0
  300. package/src/lib/components/reports/contacts-trend-card.js.map +1 -0
  301. package/src/lib/components/reports/forecast-card.d.ts +22 -0
  302. package/src/lib/components/reports/forecast-card.js +251 -0
  303. package/src/lib/components/reports/forecast-card.js.map +1 -0
  304. package/src/lib/components/reports/lead-counts.d.ts +32 -0
  305. package/src/lib/components/reports/lead-counts.js +44 -0
  306. package/src/lib/components/reports/lead-counts.js.map +1 -0
  307. package/src/lib/components/reports/lead-funnel-card.d.ts +38 -0
  308. package/src/lib/components/reports/lead-funnel-card.js +375 -0
  309. package/src/lib/components/reports/lead-funnel-card.js.map +1 -0
  310. package/src/lib/components/reports/pipeline-card.d.ts +19 -0
  311. package/src/lib/components/reports/pipeline-card.js +338 -0
  312. package/src/lib/components/reports/pipeline-card.js.map +1 -0
  313. package/src/lib/components/reports/report-bar-chart.d.ts +39 -0
  314. package/src/lib/components/reports/report-bar-chart.js +133 -0
  315. package/src/lib/components/reports/report-bar-chart.js.map +1 -0
  316. package/src/lib/components/reports/report-breakdown.d.ts +32 -0
  317. package/src/lib/components/reports/report-breakdown.js +105 -0
  318. package/src/lib/components/reports/report-breakdown.js.map +1 -0
  319. package/src/lib/components/reports/report-export.d.ts +37 -0
  320. package/src/lib/components/reports/report-export.js +66 -0
  321. package/src/lib/components/reports/report-export.js.map +1 -0
  322. package/src/lib/components/reports/report-format.d.ts +36 -0
  323. package/src/lib/components/reports/report-format.js +43 -0
  324. package/src/lib/components/reports/report-format.js.map +1 -0
  325. package/src/lib/components/reports/report-scope.d.ts +81 -0
  326. package/src/lib/components/reports/report-scope.js +58 -0
  327. package/src/lib/components/reports/report-scope.js.map +1 -0
  328. package/src/lib/components/reports/report-stat-tile.d.ts +47 -0
  329. package/src/lib/components/reports/report-stat-tile.js +96 -0
  330. package/src/lib/components/reports/report-stat-tile.js.map +1 -0
  331. package/src/lib/components/reports/source-conversion-card.d.ts +28 -0
  332. package/src/lib/components/reports/source-conversion-card.js +205 -0
  333. package/src/lib/components/reports/source-conversion-card.js.map +1 -0
  334. package/src/lib/components/reports/tasks-card.d.ts +26 -0
  335. package/src/lib/components/reports/tasks-card.js +279 -0
  336. package/src/lib/components/reports/tasks-card.js.map +1 -0
  337. package/src/lib/components/reports/use-aggregate-read.d.ts +99 -0
  338. package/src/lib/components/reports/use-aggregate-read.js +195 -0
  339. package/src/lib/components/reports/use-aggregate-read.js.map +1 -0
  340. package/src/lib/components/reports/won-lost-by-owner-card.d.ts +30 -0
  341. package/src/lib/components/reports/won-lost-by-owner-card.js +168 -0
  342. package/src/lib/components/reports/won-lost-by-owner-card.js.map +1 -0
  343. package/src/lib/components/reports-section.d.ts +42 -0
  344. package/src/lib/components/reports-section.js +308 -0
  345. package/src/lib/components/reports-section.js.map +1 -0
  346. package/src/lib/components/sending-addresses-card.d.ts +49 -0
  347. package/src/lib/components/sending-addresses-card.js +262 -0
  348. package/src/lib/components/sending-addresses-card.js.map +1 -0
  349. package/src/lib/components/settings-section.d.ts +151 -0
  350. package/src/lib/components/settings-section.js +783 -0
  351. package/src/lib/components/settings-section.js.map +1 -0
  352. package/src/lib/components/task-cells.d.ts +51 -0
  353. package/src/lib/components/task-cells.js +139 -0
  354. package/src/lib/components/task-cells.js.map +1 -0
  355. package/src/lib/components/task-edit-drawer.d.ts +53 -0
  356. package/src/lib/components/task-edit-drawer.js +483 -0
  357. package/src/lib/components/task-edit-drawer.js.map +1 -0
  358. package/src/lib/components/task-import-drawer.d.ts +24 -0
  359. package/src/lib/components/task-import-drawer.js +82 -0
  360. package/src/lib/components/task-import-drawer.js.map +1 -0
  361. package/src/lib/components/task-snooze-menu.d.ts +65 -0
  362. package/src/lib/components/task-snooze-menu.js +207 -0
  363. package/src/lib/components/task-snooze-menu.js.map +1 -0
  364. package/src/lib/components/tasks-bulk-bar.d.ts +25 -0
  365. package/src/lib/components/tasks-bulk-bar.js +348 -0
  366. package/src/lib/components/tasks-bulk-bar.js.map +1 -0
  367. package/src/lib/components/tasks-calendar.d.ts +38 -0
  368. package/src/lib/components/tasks-calendar.js +228 -0
  369. package/src/lib/components/tasks-calendar.js.map +1 -0
  370. package/src/lib/components/tasks-section.d.ts +27 -0
  371. package/src/lib/components/tasks-section.js +579 -0
  372. package/src/lib/components/tasks-section.js.map +1 -0
  373. package/src/lib/components/use-contact-campaign-emails.d.ts +32 -0
  374. package/src/lib/components/use-contact-campaign-emails.js +83 -0
  375. package/src/lib/components/use-contact-campaign-emails.js.map +1 -0
  376. package/src/lib/components/use-crm-api.d.ts +44 -0
  377. package/src/lib/components/use-crm-api.js +84 -0
  378. package/src/lib/components/use-crm-api.js.map +1 -0
  379. package/src/lib/components/use-crm-inbound-address.d.ts +60 -0
  380. package/src/lib/components/use-crm-inbound-address.js +124 -0
  381. package/src/lib/components/use-crm-inbound-address.js.map +1 -0
  382. package/src/lib/components/use-emails-hub-path.d.ts +24 -0
  383. package/src/lib/components/use-emails-hub-path.js +59 -0
  384. package/src/lib/components/use-emails-hub-path.js.map +1 -0
  385. package/src/lib/components/use-member-email-aliases.d.ts +54 -0
  386. package/src/lib/components/use-member-email-aliases.js +186 -0
  387. package/src/lib/components/use-member-email-aliases.js.map +1 -0
  388. package/src/lib/components/use-org-members.d.ts +40 -0
  389. package/src/lib/components/use-org-members.js +100 -0
  390. package/src/lib/components/use-org-members.js.map +1 -0
  391. package/src/lib/constants/api-routes.d.ts +109 -0
  392. package/src/lib/constants/api-routes.js +74 -0
  393. package/src/lib/constants/api-routes.js.map +1 -0
  394. package/src/lib/constants/bundle-common.d.ts +14 -0
  395. package/src/lib/constants/bundle-common.js +14 -0
  396. package/src/lib/constants/bundle-common.js.map +1 -0
  397. package/src/lib/constants/company-filters.d.ts +18 -0
  398. package/src/lib/constants/company-filters.js +51 -0
  399. package/src/lib/constants/company-filters.js.map +1 -0
  400. package/src/lib/constants/contact-filters.d.ts +38 -0
  401. package/src/lib/constants/contact-filters.js +294 -0
  402. package/src/lib/constants/contact-filters.js.map +1 -0
  403. package/src/lib/hooks/use-contact-field-definitions.d.ts +48 -0
  404. package/src/lib/hooks/use-contact-field-definitions.js +72 -0
  405. package/src/lib/hooks/use-contact-field-definitions.js.map +1 -0
  406. package/src/lib/hooks/use-contact-update.d.ts +25 -0
  407. package/src/lib/hooks/use-contact-update.js +80 -0
  408. package/src/lib/hooks/use-contact-update.js.map +1 -0
  409. package/src/lib/hooks/use-crm-activity-logger.d.ts +73 -0
  410. package/src/lib/hooks/use-crm-activity-logger.js +101 -0
  411. package/src/lib/hooks/use-crm-activity-logger.js.map +1 -0
  412. package/src/lib/hooks/use-crm-bulk-apply.d.ts +52 -0
  413. package/src/lib/hooks/use-crm-bulk-apply.js +112 -0
  414. package/src/lib/hooks/use-crm-bulk-apply.js.map +1 -0
  415. package/src/lib/hooks/use-crm-default-view.d.ts +24 -0
  416. package/src/lib/hooks/use-crm-default-view.js +64 -0
  417. package/src/lib/hooks/use-crm-default-view.js.map +1 -0
  418. package/src/lib/hooks/use-crm-email-templates.d.ts +59 -0
  419. package/src/lib/hooks/use-crm-email-templates.js +103 -0
  420. package/src/lib/hooks/use-crm-email-templates.js.map +1 -0
  421. package/src/lib/hooks/use-crm-hub-path.d.ts +29 -0
  422. package/src/lib/hooks/use-crm-hub-path.js +41 -0
  423. package/src/lib/hooks/use-crm-hub-path.js.map +1 -0
  424. package/src/lib/hooks/use-crm-org-mount.d.ts +97 -0
  425. package/src/lib/hooks/use-crm-org-mount.js +215 -0
  426. package/src/lib/hooks/use-crm-org-mount.js.map +1 -0
  427. package/src/lib/hooks/use-crm-record-names.d.ts +52 -0
  428. package/src/lib/hooks/use-crm-record-names.js +126 -0
  429. package/src/lib/hooks/use-crm-record-names.js.map +1 -0
  430. package/src/lib/hooks/use-crm-records-quota.d.ts +68 -0
  431. package/src/lib/hooks/use-crm-records-quota.js +118 -0
  432. package/src/lib/hooks/use-crm-records-quota.js.map +1 -0
  433. package/src/lib/hooks/use-crm-saved-view.d.ts +96 -0
  434. package/src/lib/hooks/use-crm-saved-view.js +329 -0
  435. package/src/lib/hooks/use-crm-saved-view.js.map +1 -0
  436. package/src/lib/hooks/use-crm-scope.d.ts +117 -0
  437. package/src/lib/hooks/use-crm-scope.js +147 -0
  438. package/src/lib/hooks/use-crm-scope.js.map +1 -0
  439. package/src/lib/hooks/use-crm-tasks.d.ts +85 -0
  440. package/src/lib/hooks/use-crm-tasks.js +153 -0
  441. package/src/lib/hooks/use-crm-tasks.js.map +1 -0
  442. package/src/lib/hooks/use-crm-view-grid.d.ts +55 -0
  443. package/src/lib/hooks/use-crm-view-grid.js +170 -0
  444. package/src/lib/hooks/use-crm-view-grid.js.map +1 -0
  445. package/src/lib/hooks/use-crm-views.d.ts +42 -0
  446. package/src/lib/hooks/use-crm-views.js +84 -0
  447. package/src/lib/hooks/use-crm-views.js.map +1 -0
  448. package/src/lib/hooks/use-deal-stage-api.d.ts +69 -0
  449. package/src/lib/hooks/use-deal-stage-api.js +78 -0
  450. package/src/lib/hooks/use-deal-stage-api.js.map +1 -0
  451. package/src/lib/hooks/use-deals.d.ts +47 -0
  452. package/src/lib/hooks/use-deals.js +105 -0
  453. package/src/lib/hooks/use-deals.js.map +1 -0
  454. package/src/lib/hooks/use-org-leads.d.ts +53 -0
  455. package/src/lib/hooks/use-org-leads.js +114 -0
  456. package/src/lib/hooks/use-org-leads.js.map +1 -0
  457. package/src/lib/hooks/use-org-member-directory.d.ts +36 -0
  458. package/src/lib/hooks/use-org-member-directory.js +116 -0
  459. package/src/lib/hooks/use-org-member-directory.js.map +1 -0
  460. package/src/lib/hooks/use-org-member-options.d.ts +38 -0
  461. package/src/lib/hooks/use-org-member-options.js +131 -0
  462. package/src/lib/hooks/use-org-member-options.js.map +1 -0
  463. package/src/lib/hooks/use-pipeline.d.ts +71 -0
  464. package/src/lib/hooks/use-pipeline.js +159 -0
  465. package/src/lib/hooks/use-pipeline.js.map +1 -0
  466. package/src/lib/model/companies-bulk-writes.d.ts +40 -0
  467. package/src/lib/model/companies-bulk-writes.js +103 -0
  468. package/src/lib/model/companies-bulk-writes.js.map +1 -0
  469. package/src/lib/model/companies-csv.d.ts +36 -0
  470. package/src/lib/model/companies-csv.js +38 -0
  471. package/src/lib/model/companies-csv.js.map +1 -0
  472. package/src/lib/model/companies.d.ts +99 -0
  473. package/src/lib/model/companies.js +168 -0
  474. package/src/lib/model/companies.js.map +1 -0
  475. package/src/lib/model/company-delete-route.d.ts +43 -0
  476. package/src/lib/model/company-delete-route.js +31 -0
  477. package/src/lib/model/company-delete-route.js.map +1 -0
  478. package/src/lib/model/company-delete.d.ts +42 -0
  479. package/src/lib/model/company-delete.js +52 -0
  480. package/src/lib/model/company-delete.js.map +1 -0
  481. package/src/lib/model/contact-duplicates.d.ts +58 -0
  482. package/src/lib/model/contact-duplicates.js +67 -0
  483. package/src/lib/model/contact-duplicates.js.map +1 -0
  484. package/src/lib/model/contact-record.d.ts +113 -0
  485. package/src/lib/model/contact-record.js +70 -0
  486. package/src/lib/model/contact-record.js.map +1 -0
  487. package/src/lib/model/contact-update.d.ts +93 -0
  488. package/src/lib/model/contact-update.js +50 -0
  489. package/src/lib/model/contact-update.js.map +1 -0
  490. package/src/lib/model/contacts-bulk-writes.d.ts +173 -0
  491. package/src/lib/model/contacts-bulk-writes.js +196 -0
  492. package/src/lib/model/contacts-bulk-writes.js.map +1 -0
  493. package/src/lib/model/contacts-csv.d.ts +54 -0
  494. package/src/lib/model/contacts-csv.js +67 -0
  495. package/src/lib/model/contacts-csv.js.map +1 -0
  496. package/src/lib/model/contacts-list-seed.d.ts +51 -0
  497. package/src/lib/model/contacts-list-seed.js +63 -0
  498. package/src/lib/model/contacts-list-seed.js.map +1 -0
  499. package/src/lib/model/crm-activity-report.d.ts +27 -0
  500. package/src/lib/model/crm-activity-report.js +56 -0
  501. package/src/lib/model/crm-activity-report.js.map +1 -0
  502. package/src/lib/model/crm-api.d.ts +49 -0
  503. package/src/lib/model/crm-api.js +47 -0
  504. package/src/lib/model/crm-api.js.map +1 -0
  505. package/src/lib/model/crm-bulk-writes.d.ts +147 -0
  506. package/src/lib/model/crm-bulk-writes.js +207 -0
  507. package/src/lib/model/crm-bulk-writes.js.map +1 -0
  508. package/src/lib/model/crm-company-import.d.ts +154 -0
  509. package/src/lib/model/crm-company-import.js +331 -0
  510. package/src/lib/model/crm-company-import.js.map +1 -0
  511. package/src/lib/model/crm-custom-draft.d.ts +62 -0
  512. package/src/lib/model/crm-custom-draft.js +67 -0
  513. package/src/lib/model/crm-custom-draft.js.map +1 -0
  514. package/src/lib/model/crm-deal-import.d.ts +112 -0
  515. package/src/lib/model/crm-deal-import.js +263 -0
  516. package/src/lib/model/crm-deal-import.js.map +1 -0
  517. package/src/lib/model/crm-import.d.ts +244 -0
  518. package/src/lib/model/crm-import.js +466 -0
  519. package/src/lib/model/crm-import.js.map +1 -0
  520. package/src/lib/model/crm-lead-import.d.ts +105 -0
  521. package/src/lib/model/crm-lead-import.js +255 -0
  522. package/src/lib/model/crm-lead-import.js.map +1 -0
  523. package/src/lib/model/crm-record-routes.d.ts +21 -0
  524. package/src/lib/model/crm-record-routes.js +70 -0
  525. package/src/lib/model/crm-record-routes.js.map +1 -0
  526. package/src/lib/model/crm-routes.d.ts +101 -0
  527. package/src/lib/model/crm-routes.js +92 -0
  528. package/src/lib/model/crm-routes.js.map +1 -0
  529. package/src/lib/model/crm-task-import.d.ts +94 -0
  530. package/src/lib/model/crm-task-import.js +275 -0
  531. package/src/lib/model/crm-task-import.js.map +1 -0
  532. package/src/lib/model/crm-view-param.d.ts +43 -0
  533. package/src/lib/model/crm-view-param.js +49 -0
  534. package/src/lib/model/crm-view-param.js.map +1 -0
  535. package/src/lib/model/deal-board-model.d.ts +241 -0
  536. package/src/lib/model/deal-board-model.js +439 -0
  537. package/src/lib/model/deal-board-model.js.map +1 -0
  538. package/src/lib/model/deal-form-model.d.ts +114 -0
  539. package/src/lib/model/deal-form-model.js +218 -0
  540. package/src/lib/model/deal-form-model.js.map +1 -0
  541. package/src/lib/model/deals-csv.d.ts +32 -0
  542. package/src/lib/model/deals-csv.js +37 -0
  543. package/src/lib/model/deals-csv.js.map +1 -0
  544. package/src/lib/model/import-column-shapes.d.ts +36 -0
  545. package/src/lib/model/import-column-shapes.js +76 -0
  546. package/src/lib/model/import-column-shapes.js.map +1 -0
  547. package/src/lib/model/lead-company-suggestion.d.ts +61 -0
  548. package/src/lib/model/lead-company-suggestion.js +65 -0
  549. package/src/lib/model/lead-company-suggestion.js.map +1 -0
  550. package/src/lib/model/lead-filters.d.ts +29 -0
  551. package/src/lib/model/lead-filters.js +39 -0
  552. package/src/lib/model/lead-filters.js.map +1 -0
  553. package/src/lib/model/lead-surfaces.d.ts +58 -0
  554. package/src/lib/model/lead-surfaces.js +67 -0
  555. package/src/lib/model/lead-surfaces.js.map +1 -0
  556. package/src/lib/model/leads-csv.d.ts +40 -0
  557. package/src/lib/model/leads-csv.js +40 -0
  558. package/src/lib/model/leads-csv.js.map +1 -0
  559. package/src/lib/model/next-activity-api.d.ts +31 -0
  560. package/src/lib/model/next-activity-api.js +57 -0
  561. package/src/lib/model/next-activity-api.js.map +1 -0
  562. package/src/lib/model/next-activity.d.ts +64 -0
  563. package/src/lib/model/next-activity.js +47 -0
  564. package/src/lib/model/next-activity.js.map +1 -0
  565. package/src/lib/model/person-key-web.d.ts +43 -0
  566. package/src/lib/model/person-key-web.js +52 -0
  567. package/src/lib/model/person-key-web.js.map +1 -0
  568. package/src/lib/model/record-facts.d.ts +282 -0
  569. package/src/lib/model/record-facts.js +434 -0
  570. package/src/lib/model/record-facts.js.map +1 -0
  571. package/src/lib/model/task-api.d.ts +28 -0
  572. package/src/lib/model/task-api.js +57 -0
  573. package/src/lib/model/task-api.js.map +1 -0
  574. package/src/lib/model/task-calendar.d.ts +108 -0
  575. package/src/lib/model/task-calendar.js +139 -0
  576. package/src/lib/model/task-calendar.js.map +1 -0
  577. package/src/lib/model/task-routes.d.ts +177 -0
  578. package/src/lib/model/task-routes.js +197 -0
  579. package/src/lib/model/task-routes.js.map +1 -0
  580. package/src/lib/model/task-scope.d.ts +45 -0
  581. package/src/lib/model/task-scope.js +51 -0
  582. package/src/lib/model/task-scope.js.map +1 -0
  583. package/src/lib/model/task-views.d.ts +149 -0
  584. package/src/lib/model/task-views.js +286 -0
  585. package/src/lib/model/task-views.js.map +1 -0
  586. package/src/lib/model/tasks-csv.d.ts +28 -0
  587. package/src/lib/model/tasks-csv.js +28 -0
  588. package/src/lib/model/tasks-csv.js.map +1 -0
  589. package/src/lib/plugin.d.ts +32 -0
  590. package/src/lib/plugin.js +208 -0
  591. package/src/lib/plugin.js.map +1 -0
  592. package/src/lib/server/companies-import.d.ts +57 -0
  593. package/src/lib/server/companies-import.js +242 -0
  594. package/src/lib/server/companies-import.js.map +1 -0
  595. package/src/lib/server/company-delete.d.ts +59 -0
  596. package/src/lib/server/company-delete.js +146 -0
  597. package/src/lib/server/company-delete.js.map +1 -0
  598. package/src/lib/server/contact-email-history.d.ts +82 -0
  599. package/src/lib/server/contact-email-history.js +264 -0
  600. package/src/lib/server/contact-email-history.js.map +1 -0
  601. package/src/lib/server/contact-profile.d.ts +41 -0
  602. package/src/lib/server/contact-profile.js +45 -0
  603. package/src/lib/server/contact-profile.js.map +1 -0
  604. package/src/lib/server/contact-update.d.ts +92 -0
  605. package/src/lib/server/contact-update.js +512 -0
  606. package/src/lib/server/contact-update.js.map +1 -0
  607. package/src/lib/server/contacts-import.d.ts +73 -0
  608. package/src/lib/server/contacts-import.js +263 -0
  609. package/src/lib/server/contacts-import.js.map +1 -0
  610. package/src/lib/server/contacts-merge.d.ts +86 -0
  611. package/src/lib/server/contacts-merge.js +206 -0
  612. package/src/lib/server/contacts-merge.js.map +1 -0
  613. package/src/lib/server/deals-import.d.ts +76 -0
  614. package/src/lib/server/deals-import.js +246 -0
  615. package/src/lib/server/deals-import.js.map +1 -0
  616. package/src/lib/server/email-send.d.ts +119 -0
  617. package/src/lib/server/email-send.js +667 -0
  618. package/src/lib/server/email-send.js.map +1 -0
  619. package/src/lib/server/email-template-duplicate.d.ts +19 -0
  620. package/src/lib/server/email-template-duplicate.js +206 -0
  621. package/src/lib/server/email-template-duplicate.js.map +1 -0
  622. package/src/lib/server/erase-person.d.ts +108 -0
  623. package/src/lib/server/erase-person.js +309 -0
  624. package/src/lib/server/erase-person.js.map +1 -0
  625. package/src/lib/server/import-context.d.ts +85 -0
  626. package/src/lib/server/import-context.js +181 -0
  627. package/src/lib/server/import-context.js.map +1 -0
  628. package/src/lib/server/inbound-address.d.ts +61 -0
  629. package/src/lib/server/inbound-address.js +188 -0
  630. package/src/lib/server/inbound-address.js.map +1 -0
  631. package/src/lib/server/lead-convert.d.ts +78 -0
  632. package/src/lib/server/lead-convert.js +250 -0
  633. package/src/lib/server/lead-convert.js.map +1 -0
  634. package/src/lib/server/leads-import.d.ts +84 -0
  635. package/src/lib/server/leads-import.js +261 -0
  636. package/src/lib/server/leads-import.js.map +1 -0
  637. package/src/lib/server/next-activity-routes.d.ts +33 -0
  638. package/src/lib/server/next-activity-routes.js +110 -0
  639. package/src/lib/server/next-activity-routes.js.map +1 -0
  640. package/src/lib/server/org-activity.d.ts +61 -0
  641. package/src/lib/server/org-activity.js +120 -0
  642. package/src/lib/server/org-activity.js.map +1 -0
  643. package/src/lib/server/org-caller.d.ts +110 -0
  644. package/src/lib/server/org-caller.js +154 -0
  645. package/src/lib/server/org-caller.js.map +1 -0
  646. package/src/lib/server/recipe-routes.d.ts +75 -0
  647. package/src/lib/server/recipe-routes.js +442 -0
  648. package/src/lib/server/recipe-routes.js.map +1 -0
  649. package/src/lib/server/record-facts.d.ts +65 -0
  650. package/src/lib/server/record-facts.js +337 -0
  651. package/src/lib/server/record-facts.js.map +1 -0
  652. package/src/lib/server/record-timeline.d.ts +51 -0
  653. package/src/lib/server/record-timeline.js +215 -0
  654. package/src/lib/server/record-timeline.js.map +1 -0
  655. package/src/lib/server/suite-gate.d.ts +42 -0
  656. package/src/lib/server/suite-gate.js +87 -0
  657. package/src/lib/server/suite-gate.js.map +1 -0
  658. package/src/lib/server/task-routes.d.ts +132 -0
  659. package/src/lib/server/task-routes.js +699 -0
  660. package/src/lib/server/task-routes.js.map +1 -0
  661. package/src/lib/server/tasks-import.d.ts +54 -0
  662. package/src/lib/server/tasks-import.js +157 -0
  663. package/src/lib/server/tasks-import.js.map +1 -0
  664. package/src/lib/server-deal-stage.d.ts +88 -0
  665. package/src/lib/server-deal-stage.js +316 -0
  666. package/src/lib/server-deal-stage.js.map +1 -0
  667. package/src/lib/server.d.ts +149 -0
  668. package/src/lib/server.js +615 -0
  669. package/src/lib/server.js.map +1 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../../../libs/plugins/crm/src/lib/model/task-routes.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport type { CrmTask, CrmTaskKind, CrmTaskPriority } from '@aglyn/aglyn'\n\n/**\n * The contract between the tasks console and the plugin's two task routes\n * (AGL-2599), in one module both halves import so the field a drawer sends\n * and the field a handler reads cannot drift apart.\n *\n * Route PATHS are relative to the console's plugin API prefix: the handler\n * registers `crm/task-save` and the browser calls `/api/crm/task-save`.\n */\nexport const CRM_TASK_ROUTES = {\n save: 'crm/task-save',\n complete: 'crm/task-complete',\n} as const\n\n/** The browser-side address of a route: `/api/` + the registered path. */\nexport const crmTaskRouteUrl = (\n route: (typeof CRM_TASK_ROUTES)[keyof typeof CRM_TASK_ROUTES],\n): string => `/api/${route}`\n\n/**\n * What a person may set on a task. Everything else on the document — scope,\n * provenance, status, timestamps — is the server's to stamp.\n */\nexport interface CrmTaskFields {\n title: string\n kind: CrmTaskKind\n priority: CrmTaskPriority\n dueAtMs: number | null\n assigneeUid: string | null\n notes: string\n contactId: string | null\n companyId: string | null\n dealId: string | null\n /**\n * When the assignee is reminded (AGL-2659): a time, `null` for none, or\n * ABSENT for \"nothing said\" — which the route answers with the rule in\n * `crmTaskReminderAfterEdit`: a new task's reminder is its due time, and\n * an edit that moves the due date moves a reminder that still sat on it.\n * The drawer leaves it absent until the person touches the field.\n */\n remindAtMs?: number | null\n}\n\n/**\n * Which level a task route call runs at (AGL-2637), the way\n * `readCrmRouteScope` reads it off the body.\n *\n * `hostId` alone is the SITE variant every route has always had: the org is\n * resolved from the site, the caller's role checked on it, the task stamped\n * with the site's scope. `orgId` is the ORGANIZATION variant, authorized by\n * the org for an org-wide member; a `hostId` beside it names the site a NEW\n * task is filed from, and absent, the task is the organization's own — no\n * site, `hostId: null`, the org scope token alone.\n */\nexport type CrmTaskRouteScope =\n | { hostId: string; orgId?: undefined }\n | { orgId: string; hostId?: string | null }\n\n/**\n * The scope a surface calls with, from what it holds: the mounted site, or\n * at the organization level the org the scope hook resolved. `null` until\n * the org is known, which is when a surface has nothing to call with.\n */\nexport function crmTaskCallScope(\n hostId: string | null | undefined,\n orgId: string | null | undefined,\n): CrmTaskRouteScope | null {\n if (hostId) return { hostId }\n if (orgId) return { orgId }\n return null\n}\n\nexport type CrmTaskSaveRequest = CrmTaskRouteScope & {\n /** Absent on create. */\n taskId?: string\n task: CrmTaskFields\n}\n\nexport interface CrmTaskSaveResponse {\n ok: true\n taskId: string\n /** Whether the assignee was told — false when they assigned it to themselves. */\n notified: boolean\n}\n\nexport type CrmTaskCompleteRequest = CrmTaskRouteScope & { taskId: string }\n\nexport interface CrmTaskCompleteResponse {\n ok: true\n completedAtMs: number\n /** The task was already done; nothing was written and no event fired. */\n alreadyDone?: boolean\n}\n\n/**\n * THE BATCH FORMS, organization level only (AGL-2637).\n *\n * The org hub's bulk bar completes or reassigns a selection in ONE request\n * per action: the same two routes, with `taskIds` (complete) or `tasks`\n * (save) in place of one `taskId`, authorized once by the org. Each task is\n * answered on its own — a refusal names the task and carries the route's\n * sentence — so a selection that reaches a task that has since been deleted\n * still completes the rest. The site hub keeps one request per task, where\n * each is authorized against the site.\n *\n * Capped at the list's own window: a selection cannot be larger than what\n * the list showed.\n */\nexport const CRM_TASK_BATCH_MAX = 200\n\nexport interface CrmTasksCompleteRequest {\n orgId: string\n taskIds: string[]\n}\n\nexport type CrmTaskCompleteOutcome =\n | { taskId: string; ok: true; completedAtMs: number; alreadyDone?: boolean }\n | { taskId: string; ok: false; error: string }\n\nexport interface CrmTasksCompleteResponse {\n ok: true\n results: CrmTaskCompleteOutcome[]\n}\n\nexport interface CrmTasksSaveRequest {\n orgId: string\n /** Updates only — a batch never creates. */\n tasks: Array<{ taskId: string; task: CrmTaskFields }>\n}\n\nexport type CrmTaskSaveOutcome =\n | { taskId: string; ok: true; notified: boolean }\n | { taskId: string; ok: false; error: string }\n\nexport interface CrmTasksSaveResponse {\n ok: true\n results: CrmTaskSaveOutcome[]\n}\n\nexport const CRM_TASK_TITLE_MAX = 200\nexport const CRM_TASK_NOTES_MAX = 4000\nconst RECORD_ID_MAX = 200\n\nconst KINDS: ReadonlySet<string> = new Set(['call', 'email', 'meeting', 'todo'])\nconst PRIORITIES: ReadonlySet<string> = new Set(['low', 'normal', 'high'])\n\n/**\n * A typed record id, or `null` for anything that is not one.\n *\n * A Firestore id is opaque but bounded, and it never contains a slash — a\n * slash would make it a path. Refusing here rather than storing keeps a\n * malformed link from becoming a `where` clause nothing can match.\n */\nfunction recordId(value: unknown): string | null {\n const text = String(value ?? '').trim()\n if (!text || text.length > RECORD_ID_MAX || text.includes('/')) return null\n return text\n}\n\n/**\n * The request body as a task, or the reason it is not one.\n *\n * Coerces where a person could not have meant anything else (whitespace\n * around a title, a due date sent as a string of digits) and refuses where a\n * guess would store something the list cannot show (an unknown kind, a title\n * that is nothing but spaces). The refusal is a sentence because the drawer\n * puts it in front of the person who typed the value.\n */\nexport function readCrmTaskFields(\n input: unknown,\n): { ok: true; fields: CrmTaskFields } | { ok: false; error: string } {\n const raw = (input ?? {}) as Record<string, unknown>\n const title = String(raw['title'] ?? '').trim()\n if (!title) return { ok: false, error: 'A task needs a title.' }\n if (title.length > CRM_TASK_TITLE_MAX) {\n return {\n ok: false,\n error: `A title is at most ${CRM_TASK_TITLE_MAX} characters.`,\n }\n }\n const kind = String(raw['kind'] ?? 'todo')\n if (!KINDS.has(kind)) {\n return { ok: false, error: `\"${kind}\" is not a kind of task.` }\n }\n const priority = String(raw['priority'] ?? 'normal')\n if (!PRIORITIES.has(priority)) {\n return { ok: false, error: `\"${priority}\" is not a priority.` }\n }\n const dueRaw = raw['dueAtMs']\n let dueAtMs: number | null = null\n if (dueRaw !== null && dueRaw !== undefined && dueRaw !== '') {\n const ms = Number(dueRaw)\n if (!Number.isFinite(ms) || ms <= 0) {\n return { ok: false, error: 'The due date could not be read.' }\n }\n dueAtMs = Math.round(ms)\n }\n // Three answers, not two: a reminder the body leaves out is the route's\n // to decide, and only an explicit null or empty string means \"none\".\n const remindRaw = raw['remindAtMs']\n let remindAtMs: number | null | undefined\n if (remindRaw === null || remindRaw === '') {\n remindAtMs = null\n } else if (remindRaw !== undefined) {\n const ms = Number(remindRaw)\n if (!Number.isFinite(ms) || ms <= 0) {\n return { ok: false, error: 'The reminder time could not be read.' }\n }\n remindAtMs = Math.round(ms)\n }\n const assigneeRaw = String(raw['assigneeUid'] ?? '').trim()\n const notes = String(raw['notes'] ?? '').slice(0, CRM_TASK_NOTES_MAX)\n const ids = {\n contactId: raw['contactId'] == null || raw['contactId'] === ''\n ? null\n : recordId(raw['contactId']),\n companyId: raw['companyId'] == null || raw['companyId'] === ''\n ? null\n : recordId(raw['companyId']),\n dealId: raw['dealId'] == null || raw['dealId'] === ''\n ? null\n : recordId(raw['dealId']),\n }\n for (const [field, value] of Object.entries(ids)) {\n if (value === null && raw[field] != null && raw[field] !== '') {\n return { ok: false, error: `The linked ${field.replace('Id', '')} could not be read.` }\n }\n }\n return {\n ok: true,\n fields: {\n title,\n kind: kind as CrmTaskKind,\n priority: priority as CrmTaskPriority,\n dueAtMs,\n assigneeUid: assigneeRaw || null,\n notes,\n ...ids,\n ...(remindAtMs !== undefined ? { remindAtMs } : {}),\n },\n }\n}\n\n/**\n * The stored document's editable half, as the drawer's form reads it.\n *\n * The inverse of what the save route writes, so opening a task and saving it\n * untouched is a no-op on every field the form owns.\n */\nexport function crmTaskFieldsOf(task: Partial<CrmTask>): CrmTaskFields {\n return {\n title: task.title ?? '',\n kind: task.kind ?? 'todo',\n priority: task.priority ?? 'normal',\n dueAtMs: typeof task.dueAtMs === 'number' ? task.dueAtMs : null,\n assigneeUid: task.assigneeUid || null,\n notes: task.notes ?? '',\n contactId: task.contactId || null,\n companyId: task.companyId || null,\n dealId: task.dealId || null,\n // A stored task from before reminders existed carries no field, and\n // reads as having no reminder — the same answer the route's rule gives.\n remindAtMs: typeof task.remindAtMs === 'number' ? task.remindAtMs : null,\n }\n}\n"],"names":["CRM_TASK_ROUTES","save","complete","crmTaskRouteUrl","route","crmTaskCallScope","hostId","orgId","CRM_TASK_BATCH_MAX","CRM_TASK_TITLE_MAX","CRM_TASK_NOTES_MAX","RECORD_ID_MAX","KINDS","Set","PRIORITIES","recordId","value","text","String","trim","length","includes","readCrmTaskFields","input","raw","title","ok","error","kind","has","priority","dueRaw","dueAtMs","undefined","ms","Number","isFinite","Math","round","remindRaw","remindAtMs","assigneeRaw","notes","slice","ids","contactId","companyId","dealId","field","Object","entries","replace","fields","assigneeUid","crmTaskFieldsOf","task"],"mappings":"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"}
@@ -0,0 +1,45 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Aglyn LLC
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+ import type { CrmTask } from '@aglyn/aglyn/app-utils/crm';
18
+ import { type ScopeToken } from '@aglyn/aglyn/app-utils/scope-tokens';
19
+ /**
20
+ * The `visibleTo` an ORGANIZATION task carries (AGL-2637): a task filed
21
+ * from the org hub with no site, `hostId: null`.
22
+ *
23
+ * The org token alone — the token every read set leads with, whether the
24
+ * reader is an org-wide member (the rules admit them to every row) or a
25
+ * site collaborator (whose projected read set is `['org', 'host:…']`). So
26
+ * an organization task is listed from the org hub, where a listener
27
+ * carries no scope clause, AND from every site the organization owns,
28
+ * exactly as a record the org widened to `defaultResourceScope: 'org'`
29
+ * is: `crmReadTokens` puts the org token first in every site's read set.
30
+ * What sets it apart from a widened site task is its `hostId`, not its
31
+ * scope — see {@link isOrgTask}.
32
+ *
33
+ * Frozen and shared rather than built per call because a creator that
34
+ * spelled it as `[]` would make a task nobody's listener can match.
35
+ */
36
+ export declare const CRM_ORG_TASK_SCOPE: readonly ScopeToken[];
37
+ /**
38
+ * Whether a task is the organization's own — created with no site.
39
+ *
40
+ * The site is provenance and the one fact that tells an organization task
41
+ * from a site's task the org has widened: both carry the org token. A
42
+ * completion of an org task emits no host event, because there is no site
43
+ * whose automations could hear it.
44
+ */
45
+ export declare function isOrgTask(task: Pick<Partial<CrmTask>, 'hostId'>): boolean;
@@ -0,0 +1,51 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Aglyn LLC
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */ /*
17
+ * Named beneath the entry barrel, not `@aglyn/aglyn`: the save and complete
18
+ * routes import this module, and the barrel reaches the console's React
19
+ * contexts, which the App Router's server graph refuses (AGL-405).
20
+ */ import { ORG_SCOPE_TOKEN } from "@aglyn/aglyn/app-utils/scope-tokens";
21
+ /**
22
+ * The `visibleTo` an ORGANIZATION task carries (AGL-2637): a task filed
23
+ * from the org hub with no site, `hostId: null`.
24
+ *
25
+ * The org token alone — the token every read set leads with, whether the
26
+ * reader is an org-wide member (the rules admit them to every row) or a
27
+ * site collaborator (whose projected read set is `['org', 'host:…']`). So
28
+ * an organization task is listed from the org hub, where a listener
29
+ * carries no scope clause, AND from every site the organization owns,
30
+ * exactly as a record the org widened to `defaultResourceScope: 'org'`
31
+ * is: `crmReadTokens` puts the org token first in every site's read set.
32
+ * What sets it apart from a widened site task is its `hostId`, not its
33
+ * scope — see {@link isOrgTask}.
34
+ *
35
+ * Frozen and shared rather than built per call because a creator that
36
+ * spelled it as `[]` would make a task nobody's listener can match.
37
+ */ export const CRM_ORG_TASK_SCOPE = Object.freeze([
38
+ ORG_SCOPE_TOKEN
39
+ ]);
40
+ /**
41
+ * Whether a task is the organization's own — created with no site.
42
+ *
43
+ * The site is provenance and the one fact that tells an organization task
44
+ * from a site's task the org has widened: both carry the org token. A
45
+ * completion of an org task emits no host event, because there is no site
46
+ * whose automations could hear it.
47
+ */ export function isOrgTask(task) {
48
+ return !task.hostId;
49
+ }
50
+
51
+ //# sourceMappingURL=task-scope.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../../../libs/plugins/crm/src/lib/model/task-scope.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/*\n * Named beneath the entry barrel, not `@aglyn/aglyn`: the save and complete\n * routes import this module, and the barrel reaches the console's React\n * contexts, which the App Router's server graph refuses (AGL-405).\n */\nimport type { CrmTask } from '@aglyn/aglyn/app-utils/crm'\nimport {\n ORG_SCOPE_TOKEN,\n type ScopeToken,\n} from '@aglyn/aglyn/app-utils/scope-tokens'\n\n/**\n * The `visibleTo` an ORGANIZATION task carries (AGL-2637): a task filed\n * from the org hub with no site, `hostId: null`.\n *\n * The org token alone — the token every read set leads with, whether the\n * reader is an org-wide member (the rules admit them to every row) or a\n * site collaborator (whose projected read set is `['org', 'host:…']`). So\n * an organization task is listed from the org hub, where a listener\n * carries no scope clause, AND from every site the organization owns,\n * exactly as a record the org widened to `defaultResourceScope: 'org'`\n * is: `crmReadTokens` puts the org token first in every site's read set.\n * What sets it apart from a widened site task is its `hostId`, not its\n * scope — see {@link isOrgTask}.\n *\n * Frozen and shared rather than built per call because a creator that\n * spelled it as `[]` would make a task nobody's listener can match.\n */\nexport const CRM_ORG_TASK_SCOPE: readonly ScopeToken[] = Object.freeze([\n ORG_SCOPE_TOKEN,\n])\n\n/**\n * Whether a task is the organization's own — created with no site.\n *\n * The site is provenance and the one fact that tells an organization task\n * from a site's task the org has widened: both carry the org token. A\n * completion of an org task emits no host event, because there is no site\n * whose automations could hear it.\n */\nexport function isOrgTask(task: Pick<Partial<CrmTask>, 'hostId'>): boolean {\n return !task.hostId\n}\n"],"names":["ORG_SCOPE_TOKEN","CRM_ORG_TASK_SCOPE","Object","freeze","isOrgTask","task","hostId"],"mappings":"AAAA;;;;;;;;;;;;;;;CAeC,GAED;;;;CAIC,GAED,SACEA,eAAe,QAEV,sCAAqC;AAE5C;;;;;;;;;;;;;;;;CAgBC,GACD,OAAO,MAAMC,qBAA4CC,OAAOC,MAAM,CAAC;IACrEH;CACD,EAAC;AAEF;;;;;;;CAOC,GACD,OAAO,SAASI,UAAUC,IAAsC;IAC9D,OAAO,CAACA,KAAKC,MAAM;AACrB"}
@@ -0,0 +1,149 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Aglyn LLC
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+ import { type CrmTask, type CrmTaskKind, type CrmTaskPriority, type TaskDueState } from '@aglyn/aglyn';
18
+ import type { CrmRoutes } from './crm-routes';
19
+ /**
20
+ * The tasks section's views and the query each one is (AGL-2599).
21
+ *
22
+ * Pure: what a view MEANS is written here once, as a plan the hook turns into
23
+ * Firestore constraints and a spec can read back without Firestore. "Overdue"
24
+ * and "today" are not stored on the task — nothing runs at midnight to stamp
25
+ * them — so each view is a window over `dueAtMs` computed at read time from
26
+ * the reader's own clock, and the same day boundaries {@link taskDueState}
27
+ * paints a row with.
28
+ */
29
+ export type CrmTaskView = 'mine' | 'overdue' | 'today' | 'upcoming' | 'open' | 'done';
30
+ export declare const CRM_TASK_VIEWS: ReadonlyArray<{
31
+ id: CrmTaskView;
32
+ label: string;
33
+ }>;
34
+ export declare const CRM_TASK_KINDS: readonly CrmTaskKind[];
35
+ export declare const CRM_TASK_KIND_LABELS: Record<CrmTaskKind, string>;
36
+ export declare const CRM_TASK_PRIORITIES: readonly CrmTaskPriority[];
37
+ export declare const CRM_TASK_PRIORITY_LABELS: Record<CrmTaskPriority, string>;
38
+ /**
39
+ * How many rows a view reads at most.
40
+ *
41
+ * Every view is a listener, and a listener with no cap is a bill that grows
42
+ * with the org. Two hundred is more than a person works through in a sitting
43
+ * and far under what a table paints comfortably; the list says when the
44
+ * window is full so a reader knows to narrow the view rather than assume
45
+ * the end of the table is the end of the work.
46
+ */
47
+ export declare const CRM_TASK_VIEW_LIMIT = 200;
48
+ /** Midnight at the START of the local calendar day `nowMs` falls in. */
49
+ export declare function startOfLocalDay(nowMs: number): number;
50
+ /**
51
+ * Midnight at the start of the NEXT local day — built from the calendar
52
+ * rather than by adding 24 hours, because a day that a clock change falls in
53
+ * is 23 or 25 hours long and a task due at 00:30 on that morning belongs to
54
+ * it either way.
55
+ */
56
+ export declare function startOfNextLocalDay(nowMs: number): number;
57
+ /**
58
+ * One view as constraints, in the vocabulary of the `crmTasks` indexes.
59
+ *
60
+ * `assigneeUid` narrows to the reader and rides the
61
+ * `(visibleTo, assigneeUid, status, dueAtMs)` index; every other view rides
62
+ * `(visibleTo, status, dueAtMs)`. `dueFrom` is inclusive and `dueBefore`
63
+ * exclusive so that two adjacent windows share a boundary and no task falls
64
+ * between "today" and "upcoming". A task with no due date has `dueAtMs:
65
+ * null`, which a range excludes and a bare order sorts first, so it appears
66
+ * in "My tasks" and "All open" and in none of the dated views.
67
+ */
68
+ export interface CrmTaskViewPlan {
69
+ status: 'open' | 'done';
70
+ assigneeUid?: string;
71
+ dueFrom?: number;
72
+ dueBefore?: number;
73
+ direction: 'asc' | 'desc';
74
+ }
75
+ export declare function crmTaskViewPlan(view: CrmTaskView, options: {
76
+ nowMs: number;
77
+ uid: string | null | undefined;
78
+ }): CrmTaskViewPlan;
79
+ /**
80
+ * Rows in the order a view should paint them.
81
+ *
82
+ * Firestore sorts `null` before every number, so an ascending order by
83
+ * `dueAtMs` puts the undated tasks at the TOP of "All open" — above the one
84
+ * due in an hour. The query stays as it is (the index decides that); the
85
+ * undated rows are moved to the end here, in a stable pass that leaves the
86
+ * dated order the server chose alone.
87
+ */
88
+ export declare function orderTaskRows<T extends Pick<CrmTask, 'dueAtMs'>>(rows: readonly T[]): T[];
89
+ /** The MUI palette key a due date is painted with, by its state. */
90
+ export declare const TASK_DUE_COLORS: Record<TaskDueState, string>;
91
+ /**
92
+ * The due date as a person reads it: "Overdue · Tue, Sep 1, 9:00 AM",
93
+ * "Today, 3:30 PM", "No due date". The state word comes first because it is
94
+ * the part a reader scans a column for; the timestamp is what they read once
95
+ * a row has their attention.
96
+ */
97
+ export declare function describeTaskDue(task: Pick<CrmTask, 'status' | 'dueAtMs'>, nowMs: number, locale?: string): {
98
+ state: TaskDueState;
99
+ label: string;
100
+ };
101
+ /**
102
+ * `datetime-local` ↔ epoch milliseconds, in the reader's own zone.
103
+ *
104
+ * The input's value is a wall-clock string with no zone; `new Date(string)`
105
+ * reads such a string as LOCAL time, which is what a person typing "9:00"
106
+ * into a due-date field means. Built by hand in the other direction because
107
+ * `toISOString()` would render the UTC clock, and a task due at nine would
108
+ * reopen in the drawer at whatever nine is in Greenwich.
109
+ */
110
+ export declare function dueAtToLocalInput(ms: number | null | undefined): string;
111
+ export declare function localInputToDueAt(value: string): number | null;
112
+ /**
113
+ * The two snoozes a row and the drawer offer by name (AGL-2619), in the
114
+ * order a person reaches for them; "Pick a date" is the third and takes a
115
+ * date rather than an option.
116
+ */
117
+ export type CrmTaskSnoozeOption = 'tomorrow' | 'nextWeek';
118
+ export declare const CRM_TASK_SNOOZE_OPTIONS: ReadonlyArray<{
119
+ id: CrmTaskSnoozeOption;
120
+ label: string;
121
+ }>;
122
+ /** The hour a snoozed task lands on when it had no time of day of its own. */
123
+ export declare const CRM_TASK_SNOOZE_DEFAULT_HOUR = 9;
124
+ /**
125
+ * Where a snoozed task is due next.
126
+ *
127
+ * Counted from NOW, not from the old due date: a task a week overdue
128
+ * snoozed to "tomorrow" is due tomorrow, which is what the word means to the
129
+ * person pressing it, and not due six days ago. The time of day is kept —
130
+ * a nine o'clock call stays a nine o'clock call — and a task that had no
131
+ * time lands at {@link CRM_TASK_SNOOZE_DEFAULT_HOUR}, a working hour rather
132
+ * than midnight. Built from the calendar for the reason
133
+ * {@link startOfNextLocalDay} gives.
134
+ */
135
+ export declare function snoozeDueAt(option: CrmTaskSnoozeOption, dueAtMs: number | null | undefined, nowMs: number): number;
136
+ /**
137
+ * The record a task hangs off, as a link into the hub — or `null` for a
138
+ * task that is nobody's in particular.
139
+ *
140
+ * One record per task on screen even when the document names more than one:
141
+ * the contact wins, then the deal, then the company, because that is the
142
+ * order of how specific each is about WHO the work is for. All three ids
143
+ * stay on the document for the record pages' own queries.
144
+ */
145
+ export declare function taskRecordLink(task: Pick<CrmTask, 'contactId' | 'companyId' | 'dealId'>, routes: CrmRoutes): {
146
+ kind: 'contact' | 'deal' | 'company';
147
+ id: string;
148
+ href: string;
149
+ } | null;
@@ -0,0 +1,286 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Aglyn LLC
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */ import { taskDueState } from "@aglyn/aglyn";
17
+ export const CRM_TASK_VIEWS = [
18
+ {
19
+ id: 'mine',
20
+ label: 'My tasks'
21
+ },
22
+ {
23
+ id: 'overdue',
24
+ label: 'Overdue'
25
+ },
26
+ {
27
+ id: 'today',
28
+ label: 'Today'
29
+ },
30
+ {
31
+ id: 'upcoming',
32
+ label: 'Upcoming'
33
+ },
34
+ {
35
+ id: 'open',
36
+ label: 'All open'
37
+ },
38
+ {
39
+ id: 'done',
40
+ label: 'Done'
41
+ }
42
+ ];
43
+ export const CRM_TASK_KINDS = [
44
+ 'call',
45
+ 'email',
46
+ 'meeting',
47
+ 'todo'
48
+ ];
49
+ export const CRM_TASK_KIND_LABELS = {
50
+ call: 'Call',
51
+ email: 'Email',
52
+ meeting: 'Meeting',
53
+ todo: 'To-do'
54
+ };
55
+ export const CRM_TASK_PRIORITIES = [
56
+ 'low',
57
+ 'normal',
58
+ 'high'
59
+ ];
60
+ export const CRM_TASK_PRIORITY_LABELS = {
61
+ low: 'Low',
62
+ normal: 'Normal',
63
+ high: 'High'
64
+ };
65
+ /**
66
+ * How many rows a view reads at most.
67
+ *
68
+ * Every view is a listener, and a listener with no cap is a bill that grows
69
+ * with the org. Two hundred is more than a person works through in a sitting
70
+ * and far under what a table paints comfortably; the list says when the
71
+ * window is full so a reader knows to narrow the view rather than assume
72
+ * the end of the table is the end of the work.
73
+ */ export const CRM_TASK_VIEW_LIMIT = 200;
74
+ /** Midnight at the START of the local calendar day `nowMs` falls in. */ export function startOfLocalDay(nowMs) {
75
+ const date = new Date(nowMs);
76
+ return new Date(date.getFullYear(), date.getMonth(), date.getDate()).getTime();
77
+ }
78
+ /**
79
+ * Midnight at the start of the NEXT local day — built from the calendar
80
+ * rather than by adding 24 hours, because a day that a clock change falls in
81
+ * is 23 or 25 hours long and a task due at 00:30 on that morning belongs to
82
+ * it either way.
83
+ */ export function startOfNextLocalDay(nowMs) {
84
+ const date = new Date(nowMs);
85
+ return new Date(date.getFullYear(), date.getMonth(), date.getDate() + 1).getTime();
86
+ }
87
+ export function crmTaskViewPlan(view, options) {
88
+ const { nowMs, uid } = options;
89
+ const today = startOfLocalDay(nowMs);
90
+ const tomorrow = startOfNextLocalDay(nowMs);
91
+ switch(view){
92
+ case 'mine':
93
+ return {
94
+ status: 'open',
95
+ assigneeUid: uid != null ? uid : '',
96
+ direction: 'asc'
97
+ };
98
+ case 'overdue':
99
+ return {
100
+ status: 'open',
101
+ dueBefore: today,
102
+ direction: 'asc'
103
+ };
104
+ case 'today':
105
+ return {
106
+ status: 'open',
107
+ dueFrom: today,
108
+ dueBefore: tomorrow,
109
+ direction: 'asc'
110
+ };
111
+ case 'upcoming':
112
+ return {
113
+ status: 'open',
114
+ dueFrom: tomorrow,
115
+ direction: 'asc'
116
+ };
117
+ case 'open':
118
+ return {
119
+ status: 'open',
120
+ direction: 'asc'
121
+ };
122
+ case 'done':
123
+ // Most recently due first: what was finished lately is what a reader
124
+ // scrolls the Done view for, and the oldest completed task is the one
125
+ // nobody comes back to.
126
+ return {
127
+ status: 'done',
128
+ direction: 'desc'
129
+ };
130
+ }
131
+ }
132
+ /**
133
+ * Rows in the order a view should paint them.
134
+ *
135
+ * Firestore sorts `null` before every number, so an ascending order by
136
+ * `dueAtMs` puts the undated tasks at the TOP of "All open" — above the one
137
+ * due in an hour. The query stays as it is (the index decides that); the
138
+ * undated rows are moved to the end here, in a stable pass that leaves the
139
+ * dated order the server chose alone.
140
+ */ export function orderTaskRows(rows) {
141
+ const dated = [];
142
+ const undated = [];
143
+ for (const row of rows){
144
+ ;
145
+ (typeof row.dueAtMs === 'number' ? dated : undated).push(row);
146
+ }
147
+ return [
148
+ ...dated,
149
+ ...undated
150
+ ];
151
+ }
152
+ /** The MUI palette key a due date is painted with, by its state. */ export const TASK_DUE_COLORS = {
153
+ overdue: 'error.main',
154
+ today: 'warning.main',
155
+ upcoming: 'text.primary',
156
+ none: 'text.secondary',
157
+ done: 'text.secondary'
158
+ };
159
+ /**
160
+ * The due date as a person reads it: "Overdue · Tue, Sep 1, 9:00 AM",
161
+ * "Today, 3:30 PM", "No due date". The state word comes first because it is
162
+ * the part a reader scans a column for; the timestamp is what they read once
163
+ * a row has their attention.
164
+ */ export function describeTaskDue(task, nowMs, locale) {
165
+ const state = taskDueState(task, nowMs);
166
+ const dueAtMs = task.dueAtMs;
167
+ if (typeof dueAtMs !== 'number' || !Number.isFinite(dueAtMs)) {
168
+ return {
169
+ state,
170
+ label: 'No due date'
171
+ };
172
+ }
173
+ const due = new Date(dueAtMs);
174
+ const time = due.toLocaleTimeString(locale, {
175
+ hour: 'numeric',
176
+ minute: '2-digit'
177
+ });
178
+ switch(state){
179
+ case 'today':
180
+ return {
181
+ state,
182
+ label: `Today, ${time}`
183
+ };
184
+ case 'overdue':
185
+ return {
186
+ state,
187
+ label: `Overdue · ${due.toLocaleDateString(locale, {
188
+ weekday: 'short',
189
+ month: 'short',
190
+ day: 'numeric'
191
+ })}, ${time}`
192
+ };
193
+ default:
194
+ return {
195
+ state,
196
+ label: `${due.toLocaleDateString(locale, {
197
+ weekday: 'short',
198
+ month: 'short',
199
+ day: 'numeric'
200
+ })}, ${time}`
201
+ };
202
+ }
203
+ }
204
+ /**
205
+ * `datetime-local` ↔ epoch milliseconds, in the reader's own zone.
206
+ *
207
+ * The input's value is a wall-clock string with no zone; `new Date(string)`
208
+ * reads such a string as LOCAL time, which is what a person typing "9:00"
209
+ * into a due-date field means. Built by hand in the other direction because
210
+ * `toISOString()` would render the UTC clock, and a task due at nine would
211
+ * reopen in the drawer at whatever nine is in Greenwich.
212
+ */ export function dueAtToLocalInput(ms) {
213
+ if (typeof ms !== 'number' || !Number.isFinite(ms)) return '';
214
+ const date = new Date(ms);
215
+ const pad = (value)=>String(value).padStart(2, '0');
216
+ return `${date.getFullYear()}-${pad(date.getMonth() + 1)}-` + `${pad(date.getDate())}T${pad(date.getHours())}:${pad(date.getMinutes())}`;
217
+ }
218
+ export function localInputToDueAt(value) {
219
+ const text = String(value != null ? value : '').trim();
220
+ if (!text) return null;
221
+ const ms = new Date(text).getTime();
222
+ return Number.isFinite(ms) ? ms : null;
223
+ }
224
+ export const CRM_TASK_SNOOZE_OPTIONS = [
225
+ {
226
+ id: 'tomorrow',
227
+ label: 'Tomorrow'
228
+ },
229
+ {
230
+ id: 'nextWeek',
231
+ label: 'Next week'
232
+ }
233
+ ];
234
+ /** The hour a snoozed task lands on when it had no time of day of its own. */ export const CRM_TASK_SNOOZE_DEFAULT_HOUR = 9;
235
+ /**
236
+ * Where a snoozed task is due next.
237
+ *
238
+ * Counted from NOW, not from the old due date: a task a week overdue
239
+ * snoozed to "tomorrow" is due tomorrow, which is what the word means to the
240
+ * person pressing it, and not due six days ago. The time of day is kept —
241
+ * a nine o'clock call stays a nine o'clock call — and a task that had no
242
+ * time lands at {@link CRM_TASK_SNOOZE_DEFAULT_HOUR}, a working hour rather
243
+ * than midnight. Built from the calendar for the reason
244
+ * {@link startOfNextLocalDay} gives.
245
+ */ export function snoozeDueAt(option, dueAtMs, nowMs) {
246
+ const had = typeof dueAtMs === 'number' && Number.isFinite(dueAtMs) ? new Date(dueAtMs) : null;
247
+ const hours = had ? had.getHours() : CRM_TASK_SNOOZE_DEFAULT_HOUR;
248
+ const minutes = had ? had.getMinutes() : 0;
249
+ const now = new Date(nowMs);
250
+ const days = option === 'tomorrow' ? 1 : 7;
251
+ return new Date(now.getFullYear(), now.getMonth(), now.getDate() + days, hours, minutes).getTime();
252
+ }
253
+ /**
254
+ * The record a task hangs off, as a link into the hub — or `null` for a
255
+ * task that is nobody's in particular.
256
+ *
257
+ * One record per task on screen even when the document names more than one:
258
+ * the contact wins, then the deal, then the company, because that is the
259
+ * order of how specific each is about WHO the work is for. All three ids
260
+ * stay on the document for the record pages' own queries.
261
+ */ export function taskRecordLink(task, routes) {
262
+ if (task.contactId) {
263
+ return {
264
+ kind: 'contact',
265
+ id: task.contactId,
266
+ href: routes.contact(task.contactId)
267
+ };
268
+ }
269
+ if (task.dealId) {
270
+ return {
271
+ kind: 'deal',
272
+ id: task.dealId,
273
+ href: routes.deal(task.dealId)
274
+ };
275
+ }
276
+ if (task.companyId) {
277
+ return {
278
+ kind: 'company',
279
+ id: task.companyId,
280
+ href: routes.company(task.companyId)
281
+ };
282
+ }
283
+ return null;
284
+ }
285
+
286
+ //# sourceMappingURL=task-views.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../../../libs/plugins/crm/src/lib/model/task-views.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n type CrmTask,\n type CrmTaskKind,\n type CrmTaskPriority,\n type TaskDueState,\n taskDueState,\n} from '@aglyn/aglyn'\nimport type { CrmRoutes } from './crm-routes'\n\n/**\n * The tasks section's views and the query each one is (AGL-2599).\n *\n * Pure: what a view MEANS is written here once, as a plan the hook turns into\n * Firestore constraints and a spec can read back without Firestore. \"Overdue\"\n * and \"today\" are not stored on the task — nothing runs at midnight to stamp\n * them — so each view is a window over `dueAtMs` computed at read time from\n * the reader's own clock, and the same day boundaries {@link taskDueState}\n * paints a row with.\n */\n\nexport type CrmTaskView =\n | 'mine'\n | 'overdue'\n | 'today'\n | 'upcoming'\n | 'open'\n | 'done'\n\nexport const CRM_TASK_VIEWS: ReadonlyArray<{ id: CrmTaskView; label: string }> =\n [\n { id: 'mine', label: 'My tasks' },\n { id: 'overdue', label: 'Overdue' },\n { id: 'today', label: 'Today' },\n { id: 'upcoming', label: 'Upcoming' },\n { id: 'open', label: 'All open' },\n { id: 'done', label: 'Done' },\n ]\n\nexport const CRM_TASK_KINDS: readonly CrmTaskKind[] = [\n 'call',\n 'email',\n 'meeting',\n 'todo',\n]\n\nexport const CRM_TASK_KIND_LABELS: Record<CrmTaskKind, string> = {\n call: 'Call',\n email: 'Email',\n meeting: 'Meeting',\n todo: 'To-do',\n}\n\nexport const CRM_TASK_PRIORITIES: readonly CrmTaskPriority[] = [\n 'low',\n 'normal',\n 'high',\n]\n\nexport const CRM_TASK_PRIORITY_LABELS: Record<CrmTaskPriority, string> = {\n low: 'Low',\n normal: 'Normal',\n high: 'High',\n}\n\n/**\n * How many rows a view reads at most.\n *\n * Every view is a listener, and a listener with no cap is a bill that grows\n * with the org. Two hundred is more than a person works through in a sitting\n * and far under what a table paints comfortably; the list says when the\n * window is full so a reader knows to narrow the view rather than assume\n * the end of the table is the end of the work.\n */\nexport const CRM_TASK_VIEW_LIMIT = 200\n\n/** Midnight at the START of the local calendar day `nowMs` falls in. */\nexport function startOfLocalDay(nowMs: number): number {\n const date = new Date(nowMs)\n return new Date(date.getFullYear(), date.getMonth(), date.getDate()).getTime()\n}\n\n/**\n * Midnight at the start of the NEXT local day — built from the calendar\n * rather than by adding 24 hours, because a day that a clock change falls in\n * is 23 or 25 hours long and a task due at 00:30 on that morning belongs to\n * it either way.\n */\nexport function startOfNextLocalDay(nowMs: number): number {\n const date = new Date(nowMs)\n return new Date(\n date.getFullYear(),\n date.getMonth(),\n date.getDate() + 1,\n ).getTime()\n}\n\n/**\n * One view as constraints, in the vocabulary of the `crmTasks` indexes.\n *\n * `assigneeUid` narrows to the reader and rides the\n * `(visibleTo, assigneeUid, status, dueAtMs)` index; every other view rides\n * `(visibleTo, status, dueAtMs)`. `dueFrom` is inclusive and `dueBefore`\n * exclusive so that two adjacent windows share a boundary and no task falls\n * between \"today\" and \"upcoming\". A task with no due date has `dueAtMs:\n * null`, which a range excludes and a bare order sorts first, so it appears\n * in \"My tasks\" and \"All open\" and in none of the dated views.\n */\nexport interface CrmTaskViewPlan {\n status: 'open' | 'done'\n assigneeUid?: string\n dueFrom?: number\n dueBefore?: number\n direction: 'asc' | 'desc'\n}\n\nexport function crmTaskViewPlan(\n view: CrmTaskView,\n options: { nowMs: number; uid: string | null | undefined },\n): CrmTaskViewPlan {\n const { nowMs, uid } = options\n const today = startOfLocalDay(nowMs)\n const tomorrow = startOfNextLocalDay(nowMs)\n switch (view) {\n case 'mine':\n return { status: 'open', assigneeUid: uid ?? '', direction: 'asc' }\n case 'overdue':\n return { status: 'open', dueBefore: today, direction: 'asc' }\n case 'today':\n return { status: 'open', dueFrom: today, dueBefore: tomorrow, direction: 'asc' }\n case 'upcoming':\n return { status: 'open', dueFrom: tomorrow, direction: 'asc' }\n case 'open':\n return { status: 'open', direction: 'asc' }\n case 'done':\n // Most recently due first: what was finished lately is what a reader\n // scrolls the Done view for, and the oldest completed task is the one\n // nobody comes back to.\n return { status: 'done', direction: 'desc' }\n }\n}\n\n/**\n * Rows in the order a view should paint them.\n *\n * Firestore sorts `null` before every number, so an ascending order by\n * `dueAtMs` puts the undated tasks at the TOP of \"All open\" — above the one\n * due in an hour. The query stays as it is (the index decides that); the\n * undated rows are moved to the end here, in a stable pass that leaves the\n * dated order the server chose alone.\n */\nexport function orderTaskRows<T extends Pick<CrmTask, 'dueAtMs'>>(\n rows: readonly T[],\n): T[] {\n const dated: T[] = []\n const undated: T[] = []\n for (const row of rows) {\n ;(typeof row.dueAtMs === 'number' ? dated : undated).push(row)\n }\n return [...dated, ...undated]\n}\n\n/** The MUI palette key a due date is painted with, by its state. */\nexport const TASK_DUE_COLORS: Record<TaskDueState, string> = {\n overdue: 'error.main',\n today: 'warning.main',\n upcoming: 'text.primary',\n none: 'text.secondary',\n done: 'text.secondary',\n}\n\n/**\n * The due date as a person reads it: \"Overdue · Tue, Sep 1, 9:00 AM\",\n * \"Today, 3:30 PM\", \"No due date\". The state word comes first because it is\n * the part a reader scans a column for; the timestamp is what they read once\n * a row has their attention.\n */\nexport function describeTaskDue(\n task: Pick<CrmTask, 'status' | 'dueAtMs'>,\n nowMs: number,\n locale?: string,\n): { state: TaskDueState; label: string } {\n const state = taskDueState(task, nowMs)\n const dueAtMs = task.dueAtMs\n if (typeof dueAtMs !== 'number' || !Number.isFinite(dueAtMs)) {\n return { state, label: 'No due date' }\n }\n const due = new Date(dueAtMs)\n const time = due.toLocaleTimeString(locale, {\n hour: 'numeric',\n minute: '2-digit',\n })\n switch (state) {\n case 'today':\n return { state, label: `Today, ${time}` }\n case 'overdue':\n return {\n state,\n label: `Overdue · ${due.toLocaleDateString(locale, {\n weekday: 'short',\n month: 'short',\n day: 'numeric',\n })}, ${time}`,\n }\n default:\n return {\n state,\n label: `${due.toLocaleDateString(locale, {\n weekday: 'short',\n month: 'short',\n day: 'numeric',\n })}, ${time}`,\n }\n }\n}\n\n/**\n * `datetime-local` ↔ epoch milliseconds, in the reader's own zone.\n *\n * The input's value is a wall-clock string with no zone; `new Date(string)`\n * reads such a string as LOCAL time, which is what a person typing \"9:00\"\n * into a due-date field means. Built by hand in the other direction because\n * `toISOString()` would render the UTC clock, and a task due at nine would\n * reopen in the drawer at whatever nine is in Greenwich.\n */\nexport function dueAtToLocalInput(ms: number | null | undefined): string {\n if (typeof ms !== 'number' || !Number.isFinite(ms)) return ''\n const date = new Date(ms)\n const pad = (value: number) => String(value).padStart(2, '0')\n return (\n `${date.getFullYear()}-${pad(date.getMonth() + 1)}-` +\n `${pad(date.getDate())}T${pad(date.getHours())}:${pad(date.getMinutes())}`\n )\n}\n\nexport function localInputToDueAt(value: string): number | null {\n const text = String(value ?? '').trim()\n if (!text) return null\n const ms = new Date(text).getTime()\n return Number.isFinite(ms) ? ms : null\n}\n\n/**\n * The two snoozes a row and the drawer offer by name (AGL-2619), in the\n * order a person reaches for them; \"Pick a date\" is the third and takes a\n * date rather than an option.\n */\nexport type CrmTaskSnoozeOption = 'tomorrow' | 'nextWeek'\n\nexport const CRM_TASK_SNOOZE_OPTIONS: ReadonlyArray<{\n id: CrmTaskSnoozeOption\n label: string\n}> = [\n { id: 'tomorrow', label: 'Tomorrow' },\n { id: 'nextWeek', label: 'Next week' },\n]\n\n/** The hour a snoozed task lands on when it had no time of day of its own. */\nexport const CRM_TASK_SNOOZE_DEFAULT_HOUR = 9\n\n/**\n * Where a snoozed task is due next.\n *\n * Counted from NOW, not from the old due date: a task a week overdue\n * snoozed to \"tomorrow\" is due tomorrow, which is what the word means to the\n * person pressing it, and not due six days ago. The time of day is kept —\n * a nine o'clock call stays a nine o'clock call — and a task that had no\n * time lands at {@link CRM_TASK_SNOOZE_DEFAULT_HOUR}, a working hour rather\n * than midnight. Built from the calendar for the reason\n * {@link startOfNextLocalDay} gives.\n */\nexport function snoozeDueAt(\n option: CrmTaskSnoozeOption,\n dueAtMs: number | null | undefined,\n nowMs: number,\n): number {\n const had = typeof dueAtMs === 'number' && Number.isFinite(dueAtMs) ? new Date(dueAtMs) : null\n const hours = had ? had.getHours() : CRM_TASK_SNOOZE_DEFAULT_HOUR\n const minutes = had ? had.getMinutes() : 0\n const now = new Date(nowMs)\n const days = option === 'tomorrow' ? 1 : 7\n return new Date(\n now.getFullYear(),\n now.getMonth(),\n now.getDate() + days,\n hours,\n minutes,\n ).getTime()\n}\n\n/**\n * The record a task hangs off, as a link into the hub — or `null` for a\n * task that is nobody's in particular.\n *\n * One record per task on screen even when the document names more than one:\n * the contact wins, then the deal, then the company, because that is the\n * order of how specific each is about WHO the work is for. All three ids\n * stay on the document for the record pages' own queries.\n */\nexport function taskRecordLink(\n task: Pick<CrmTask, 'contactId' | 'companyId' | 'dealId'>,\n routes: CrmRoutes,\n): { kind: 'contact' | 'deal' | 'company'; id: string; href: string } | null {\n if (task.contactId) {\n return { kind: 'contact', id: task.contactId, href: routes.contact(task.contactId) }\n }\n if (task.dealId) {\n return { kind: 'deal', id: task.dealId, href: routes.deal(task.dealId) }\n }\n if (task.companyId) {\n return { kind: 'company', id: task.companyId, href: routes.company(task.companyId) }\n }\n return null\n}\n"],"names":["taskDueState","CRM_TASK_VIEWS","id","label","CRM_TASK_KINDS","CRM_TASK_KIND_LABELS","call","email","meeting","todo","CRM_TASK_PRIORITIES","CRM_TASK_PRIORITY_LABELS","low","normal","high","CRM_TASK_VIEW_LIMIT","startOfLocalDay","nowMs","date","Date","getFullYear","getMonth","getDate","getTime","startOfNextLocalDay","crmTaskViewPlan","view","options","uid","today","tomorrow","status","assigneeUid","direction","dueBefore","dueFrom","orderTaskRows","rows","dated","undated","row","dueAtMs","push","TASK_DUE_COLORS","overdue","upcoming","none","done","describeTaskDue","task","locale","state","Number","isFinite","due","time","toLocaleTimeString","hour","minute","toLocaleDateString","weekday","month","day","dueAtToLocalInput","ms","pad","value","String","padStart","getHours","getMinutes","localInputToDueAt","text","trim","CRM_TASK_SNOOZE_OPTIONS","CRM_TASK_SNOOZE_DEFAULT_HOUR","snoozeDueAt","option","had","hours","minutes","now","days","taskRecordLink","routes","contactId","kind","href","contact","dealId","deal","companyId","company"],"mappings":"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"}
@@ -0,0 +1,28 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Aglyn LLC
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+ /**
18
+ * The tasks CSV — one file from the section's Export button and the bulk
19
+ * bar's (AGL-2621).
20
+ *
21
+ * A task hangs off a contact, a company or a deal by id; the file names
22
+ * each by the name the list already resolved for the row, so a spreadsheet
23
+ * reads "Acme" and not a document id. The assignee is written by address
24
+ * for the same reason. A due date is an INSTANT — a task due at nine is due
25
+ * at nine in the assignee's zone — so it is written as an ISO timestamp,
26
+ * and a spreadsheet renders it in whatever zone it is opened in.
27
+ */
28
+ export { TASK_CSV_COLUMNS, tasksCsv, type TaskCsvOptions, type TaskCsvRow, } from '@aglyn/aglyn';