@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,28 @@
1
+ import { type CrmReportScope } from './report-scope';
2
+ export interface SourceConversionCardProps {
3
+ report: CrmReportScope;
4
+ }
5
+ /**
6
+ * Conversion by source (AGL-2624): of the people captured through each
7
+ * door in the period, how many are customers now.
8
+ *
9
+ * A COHORT by capture date, not a count of purchases in the period: the
10
+ * question is "how well does each source convert", and the honest
11
+ * population for it is the people that source brought in, followed to
12
+ * where they stand today. A form lead captured on day one and buying on
13
+ * day twenty is a conversion the form earned; a customer captured last
14
+ * year who bought again this month is not evidence about this period's
15
+ * doors. So the window is the period's contacts by `createdAt` — the
16
+ * `(visibleTo, createdAt)` index the trend card counts through — and
17
+ * "customer" is read off the facet: the stage at `customer` or past it,
18
+ * or an order on the books whatever the stage says.
19
+ *
20
+ * Through THIS group's facet, like every by-source figure: a source is
21
+ * which of this business's doors the person came through, and a stage is
22
+ * where this business's team put them.
23
+ */
24
+ export declare function SourceConversionCard(props: SourceConversionCardProps): import("react").JSX.Element;
25
+ export declare namespace SourceConversionCard {
26
+ var displayName: string;
27
+ }
28
+ export default SourceConversionCard;
@@ -0,0 +1,205 @@
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
+ */ 'use client';
17
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
18
+ import * as Aglyn from "@aglyn/aglyn";
19
+ import { CardDisplay } from "@aglyn/shared-ui-jsx";
20
+ import { measuredRate, percent, Section } from "@aglyn/shared-ui-jsx/components/measured-figures.component";
21
+ import { ScrollTable } from "@aglyn/shared-ui-jsx/components/scroll-table.component";
22
+ import { Alert, Stack, TableBody, TableCell, TableHead, TableRow, Typography } from "@mui/material";
23
+ import { getCountFromServer, limit, orderBy, query, Timestamp, where } from "firebase/firestore";
24
+ import { useMemo } from "react";
25
+ import { useFirestore } from "@aglyn/tenant-feature-instance";
26
+ import { ReportExport } from "./report-export.js";
27
+ import { reportFilename } from "./report-format.js";
28
+ import { reportCacheKey, scopedCollection, visibleToClause } from "./report-scope.js";
29
+ import { ReportStatTile } from "./report-stat-tile.js";
30
+ import { useAggregateRead, useWindowRead } from "./use-aggregate-read.js";
31
+ /**
32
+ * How many of the period's contacts the by-source table is read from.
33
+ *
34
+ * The captured count is a server aggregate and never meets this bound;
35
+ * the table needs each contact's sources and stage off this holder's
36
+ * facet, which no aggregate can read, so it reads the period's newest
37
+ * thousand and says when there were more — the same bound the sources
38
+ * mix keeps, over the period rather than all time.
39
+ */ const CONTACT_CEILING = 1000;
40
+ /** The table's columns, which are also the CSV's. */ const COLUMNS = [
41
+ 'Source',
42
+ 'Captured',
43
+ 'Customers',
44
+ 'Conversion'
45
+ ];
46
+ /**
47
+ * Conversion by source (AGL-2624): of the people captured through each
48
+ * door in the period, how many are customers now.
49
+ *
50
+ * A COHORT by capture date, not a count of purchases in the period: the
51
+ * question is "how well does each source convert", and the honest
52
+ * population for it is the people that source brought in, followed to
53
+ * where they stand today. A form lead captured on day one and buying on
54
+ * day twenty is a conversion the form earned; a customer captured last
55
+ * year who bought again this month is not evidence about this period's
56
+ * doors. So the window is the period's contacts by `createdAt` — the
57
+ * `(visibleTo, createdAt)` index the trend card counts through — and
58
+ * "customer" is read off the facet: the stage at `customer` or past it,
59
+ * or an order on the books whatever the stage says.
60
+ *
61
+ * Through THIS group's facet, like every by-source figure: a source is
62
+ * which of this business's doors the person came through, and a stage is
63
+ * where this business's team put them.
64
+ */ export function SourceConversionCard(props) {
65
+ const { report } = props;
66
+ const { scope, tokens, groupId, range, period, routes } = report;
67
+ const firestore = useFirestore();
68
+ const capturedInPeriod = ()=>query(scopedCollection(firestore, scope, 'contacts'), ...visibleToClause(tokens), where('createdAt', '>=', Timestamp.fromMillis(range.from)), where('createdAt', '<', Timestamp.fromMillis(range.to)));
69
+ const captured = useAggregateRead(()=>getCountFromServer(capturedInPeriod()).then((snapshot)=>snapshot.data().count), [
70
+ firestore,
71
+ scope,
72
+ tokens,
73
+ range
74
+ ], {
75
+ cacheKey: reportCacheKey(report, 'sources:captured')
76
+ });
77
+ const window = useWindowRead(()=>query(capturedInPeriod(), orderBy('createdAt', 'desc'), limit(CONTACT_CEILING + 1)), CONTACT_CEILING, [
78
+ firestore,
79
+ scope,
80
+ tokens,
81
+ range
82
+ ], {
83
+ cacheKey: reportCacheKey(report, 'sources:window')
84
+ });
85
+ const status = window.status;
86
+ const conversion = useMemo(()=>Aglyn.conversionBySource(window.rows.map((row)=>Aglyn.readContactFacet(row, groupId))), [
87
+ window,
88
+ groupId
89
+ ]);
90
+ const read = status === 'success';
91
+ const rate = read ? measuredRate(conversion.customers, conversion.total, 'captured') : null;
92
+ const labelOf = (source)=>{
93
+ var _Aglyn_CONTACT_SOURCE_LABELS_source;
94
+ return (_Aglyn_CONTACT_SOURCE_LABELS_source = Aglyn.CONTACT_SOURCE_LABELS[source]) != null ? _Aglyn_CONTACT_SOURCE_LABELS_source : source;
95
+ };
96
+ const sampled = read && (window.truncated || captured.value !== null && captured.value > window.rows.length);
97
+ const caption = sampled ? `Read from the ${window.rows.length.toLocaleString()} most recently captured contacts` + (captured.value !== null ? ` of ${captured.value.toLocaleString()}` : '') + ' in the period; the captured tile is counted on the server.' : undefined;
98
+ return /*#__PURE__*/ _jsx(CardDisplay, {
99
+ header: 'Conversion by source',
100
+ help: Aglyn.pluginDocsHelp('crmReports', {
101
+ anchor: '#conversion-by-source',
102
+ excerpt: 'Of the people each capture surface brought in during the ' + 'period, how many are customers now — at the customer stage or ' + 'past it, or with an order on the books. Read through this ' + 'site’s own view of each person.'
103
+ }),
104
+ contentGutterX: true,
105
+ contentGutterY: true,
106
+ children: /*#__PURE__*/ _jsxs(Stack, {
107
+ spacing: 2,
108
+ children: [
109
+ /*#__PURE__*/ _jsxs(Stack, {
110
+ direction: "row",
111
+ spacing: 3,
112
+ sx: {
113
+ flexWrap: 'wrap'
114
+ },
115
+ children: [
116
+ /*#__PURE__*/ _jsx(ReportStatTile, {
117
+ label: 'Captured',
118
+ value: captured.value !== null ? captured.value.toLocaleString() : null,
119
+ note: 'in the period, counted on the server',
120
+ href: routes.section('contacts')
121
+ }),
122
+ /*#__PURE__*/ _jsx(ReportStatTile, {
123
+ label: 'Now customers',
124
+ value: read ? conversion.customers.toLocaleString() : null,
125
+ note: 'of those captured'
126
+ }),
127
+ /*#__PURE__*/ _jsx(ReportStatTile, {
128
+ label: 'Conversion',
129
+ value: rate ? percent(rate.value) : null,
130
+ note: rate ? `${rate.numerator.toLocaleString()} of ${rate.denominator.toLocaleString()} ${rate.denominatorLabel}` : read ? 'nobody captured in the period' : undefined
131
+ })
132
+ ]
133
+ }),
134
+ captured.status === 'error' || status === 'error' ? /*#__PURE__*/ _jsx(Alert, {
135
+ severity: "warning",
136
+ children: 'The period’s contacts could not be read.'
137
+ }) : null,
138
+ /*#__PURE__*/ _jsxs(Section, {
139
+ title: 'By source',
140
+ children: [
141
+ conversion.rows.length ? /*#__PURE__*/ _jsxs(ScrollTable, {
142
+ size: "small",
143
+ children: [
144
+ /*#__PURE__*/ _jsx(TableHead, {
145
+ children: /*#__PURE__*/ _jsx(TableRow, {
146
+ children: COLUMNS.map((column, index)=>/*#__PURE__*/ _jsx(TableCell, {
147
+ align: index ? 'right' : 'left',
148
+ children: column
149
+ }, column))
150
+ })
151
+ }),
152
+ /*#__PURE__*/ _jsx(TableBody, {
153
+ children: conversion.rows.map((row)=>/*#__PURE__*/ _jsxs(TableRow, {
154
+ children: [
155
+ /*#__PURE__*/ _jsx(TableCell, {
156
+ children: labelOf(row.source)
157
+ }),
158
+ /*#__PURE__*/ _jsx(TableCell, {
159
+ align: "right",
160
+ children: row.captured.toLocaleString()
161
+ }),
162
+ /*#__PURE__*/ _jsx(TableCell, {
163
+ align: "right",
164
+ children: row.customers.toLocaleString()
165
+ }),
166
+ /*#__PURE__*/ _jsx(TableCell, {
167
+ align: "right",
168
+ children: percent(row.rate)
169
+ })
170
+ ]
171
+ }, row.source))
172
+ })
173
+ ]
174
+ }) : /*#__PURE__*/ _jsx(Typography, {
175
+ variant: "body2",
176
+ color: "text.secondary",
177
+ children: status === 'loading' ? 'Reading…' : 'Nobody captured in this period.'
178
+ }),
179
+ conversion.rows.length ? /*#__PURE__*/ _jsx(Typography, {
180
+ variant: "caption",
181
+ color: "text.secondary",
182
+ children: 'A person captured two ways counts under both.' + (conversion.unsourced ? ` ${conversion.unsourced.toLocaleString()} with no source on this site are counted in the tiles only.` : '')
183
+ }) : null,
184
+ /*#__PURE__*/ _jsx(ReportExport, {
185
+ filename: reportFilename('conversion-by-source', period),
186
+ columns: COLUMNS,
187
+ rows: ()=>conversion.rows.map((row)=>[
188
+ labelOf(row.source),
189
+ row.captured,
190
+ row.customers,
191
+ percent(row.rate)
192
+ ]),
193
+ disabled: !read || !conversion.rows.length,
194
+ caption: caption
195
+ })
196
+ ]
197
+ })
198
+ ]
199
+ })
200
+ });
201
+ }
202
+ SourceConversionCard.displayName = 'SourceConversionCard';
203
+ export default SourceConversionCard;
204
+
205
+ //# sourceMappingURL=source-conversion-card.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../../../../libs/plugins/crm/src/lib/components/reports/source-conversion-card.tsx"],"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'use client'\n\nimport * as Aglyn from '@aglyn/aglyn'\nimport { CardDisplay } from '@aglyn/shared-ui-jsx'\nimport {\n measuredRate,\n percent,\n Section,\n} from '@aglyn/shared-ui-jsx/components/measured-figures.component'\nimport { ScrollTable } from '@aglyn/shared-ui-jsx/components/scroll-table.component'\nimport {\n Alert,\n Stack,\n TableBody,\n TableCell,\n TableHead,\n TableRow,\n Typography,\n} from '@mui/material'\nimport {\n getCountFromServer,\n limit,\n orderBy,\n query,\n Timestamp,\n where,\n} from 'firebase/firestore'\nimport { useMemo } from 'react'\nimport { useFirestore } from '@aglyn/tenant-feature-instance'\nimport { ReportExport } from './report-export'\nimport { reportFilename } from './report-format'\nimport {\n type CrmReportScope,\n reportCacheKey,\n scopedCollection,\n visibleToClause,\n} from './report-scope'\nimport { ReportStatTile } from './report-stat-tile'\nimport { useAggregateRead, useWindowRead } from './use-aggregate-read'\n\n/**\n * How many of the period's contacts the by-source table is read from.\n *\n * The captured count is a server aggregate and never meets this bound;\n * the table needs each contact's sources and stage off this holder's\n * facet, which no aggregate can read, so it reads the period's newest\n * thousand and says when there were more — the same bound the sources\n * mix keeps, over the period rather than all time.\n */\nconst CONTACT_CEILING = 1000\n\n/** The table's columns, which are also the CSV's. */\nconst COLUMNS = ['Source', 'Captured', 'Customers', 'Conversion'] as const\n\nexport interface SourceConversionCardProps {\n report: CrmReportScope\n}\n\n/**\n * Conversion by source (AGL-2624): of the people captured through each\n * door in the period, how many are customers now.\n *\n * A COHORT by capture date, not a count of purchases in the period: the\n * question is \"how well does each source convert\", and the honest\n * population for it is the people that source brought in, followed to\n * where they stand today. A form lead captured on day one and buying on\n * day twenty is a conversion the form earned; a customer captured last\n * year who bought again this month is not evidence about this period's\n * doors. So the window is the period's contacts by `createdAt` — the\n * `(visibleTo, createdAt)` index the trend card counts through — and\n * \"customer\" is read off the facet: the stage at `customer` or past it,\n * or an order on the books whatever the stage says.\n *\n * Through THIS group's facet, like every by-source figure: a source is\n * which of this business's doors the person came through, and a stage is\n * where this business's team put them.\n */\nexport function SourceConversionCard(props: SourceConversionCardProps) {\n const { report } = props\n const { scope, tokens, groupId, range, period, routes } = report\n const firestore = useFirestore()\n\n const capturedInPeriod = () =>\n query(\n scopedCollection(firestore, scope, 'contacts'),\n ...visibleToClause(tokens),\n where('createdAt', '>=', Timestamp.fromMillis(range.from)),\n where('createdAt', '<', Timestamp.fromMillis(range.to)),\n )\n\n const captured = useAggregateRead<number>(\n () => getCountFromServer(capturedInPeriod()).then((snapshot) => snapshot.data().count),\n [firestore, scope, tokens, range],\n { cacheKey: reportCacheKey(report, 'sources:captured') },\n )\n const window = useWindowRead<Record<string, unknown>>(\n () =>\n query(\n capturedInPeriod(),\n orderBy('createdAt', 'desc'),\n limit(CONTACT_CEILING + 1),\n ),\n CONTACT_CEILING,\n [firestore, scope, tokens, range],\n { cacheKey: reportCacheKey(report, 'sources:window') },\n )\n const status = window.status\n\n const conversion = useMemo(\n () =>\n Aglyn.conversionBySource(\n window.rows.map((row) => Aglyn.readContactFacet(row, groupId)),\n ),\n [window, groupId],\n )\n const read = status === 'success'\n const rate = read\n ? measuredRate(conversion.customers, conversion.total, 'captured')\n : null\n const labelOf = (source: Aglyn.ContactSource): string =>\n Aglyn.CONTACT_SOURCE_LABELS[source] ?? source\n const sampled =\n read &&\n (window.truncated ||\n (captured.value !== null && captured.value > window.rows.length))\n const caption = sampled\n ? `Read from the ${window.rows.length.toLocaleString()} most recently captured contacts` +\n (captured.value !== null ? ` of ${captured.value.toLocaleString()}` : '') +\n ' in the period; the captured tile is counted on the server.'\n : undefined\n\n return (\n <CardDisplay\n header={'Conversion by source'}\n help={Aglyn.pluginDocsHelp('crmReports', {\n anchor: '#conversion-by-source',\n excerpt:\n 'Of the people each capture surface brought in during the ' +\n 'period, how many are customers now — at the customer stage or ' +\n 'past it, or with an order on the books. Read through this ' +\n 'site’s own view of each person.',\n })}\n contentGutterX\n contentGutterY\n >\n <Stack spacing={2}>\n <Stack direction=\"row\" spacing={3} sx={{ flexWrap: 'wrap' }}>\n <ReportStatTile\n label={'Captured'}\n value={captured.value !== null ? captured.value.toLocaleString() : null}\n note={'in the period, counted on the server'}\n href={routes.section('contacts')}\n />\n <ReportStatTile\n label={'Now customers'}\n value={read ? conversion.customers.toLocaleString() : null}\n note={'of those captured'}\n />\n <ReportStatTile\n label={'Conversion'}\n value={rate ? percent(rate.value) : null}\n note={\n rate\n ? `${rate.numerator.toLocaleString()} of ${rate.denominator.toLocaleString()} ${rate.denominatorLabel}`\n : read\n ? 'nobody captured in the period'\n : undefined\n }\n />\n </Stack>\n {captured.status === 'error' || status === 'error' ? (\n <Alert severity=\"warning\">{'The period’s contacts could not be read.'}</Alert>\n ) : null}\n <Section title={'By source'}>\n {conversion.rows.length ? (\n <ScrollTable size=\"small\">\n <TableHead>\n <TableRow>\n {COLUMNS.map((column, index) => (\n <TableCell key={column} align={index ? 'right' : 'left'}>\n {column}\n </TableCell>\n ))}\n </TableRow>\n </TableHead>\n <TableBody>\n {conversion.rows.map((row) => (\n <TableRow key={row.source}>\n <TableCell>{labelOf(row.source)}</TableCell>\n <TableCell align=\"right\">{row.captured.toLocaleString()}</TableCell>\n <TableCell align=\"right\">{row.customers.toLocaleString()}</TableCell>\n <TableCell align=\"right\">{percent(row.rate)}</TableCell>\n </TableRow>\n ))}\n </TableBody>\n </ScrollTable>\n ) : (\n <Typography variant=\"body2\" color=\"text.secondary\">\n {status === 'loading' ? 'Reading…' : 'Nobody captured in this period.'}\n </Typography>\n )}\n {conversion.rows.length ? (\n <Typography variant=\"caption\" color=\"text.secondary\">\n {'A person captured two ways counts under both.' +\n (conversion.unsourced\n ? ` ${conversion.unsourced.toLocaleString()} with no source on this site are counted in the tiles only.`\n : '')}\n </Typography>\n ) : null}\n <ReportExport\n filename={reportFilename('conversion-by-source', period)}\n columns={COLUMNS}\n rows={() =>\n conversion.rows.map((row) => [\n labelOf(row.source),\n row.captured,\n row.customers,\n percent(row.rate),\n ])\n }\n disabled={!read || !conversion.rows.length}\n caption={caption}\n />\n </Section>\n </Stack>\n </CardDisplay>\n )\n}\nSourceConversionCard.displayName = 'SourceConversionCard'\n\nexport default SourceConversionCard\n"],"names":["Aglyn","CardDisplay","measuredRate","percent","Section","ScrollTable","Alert","Stack","TableBody","TableCell","TableHead","TableRow","Typography","getCountFromServer","limit","orderBy","query","Timestamp","where","useMemo","useFirestore","ReportExport","reportFilename","reportCacheKey","scopedCollection","visibleToClause","ReportStatTile","useAggregateRead","useWindowRead","CONTACT_CEILING","COLUMNS","SourceConversionCard","props","report","scope","tokens","groupId","range","period","routes","firestore","capturedInPeriod","fromMillis","from","to","captured","then","snapshot","data","count","cacheKey","window","status","conversion","conversionBySource","rows","map","row","readContactFacet","read","rate","customers","total","labelOf","source","CONTACT_SOURCE_LABELS","sampled","truncated","value","length","caption","toLocaleString","undefined","header","help","pluginDocsHelp","anchor","excerpt","contentGutterX","contentGutterY","spacing","direction","sx","flexWrap","label","note","href","section","numerator","denominator","denominatorLabel","severity","title","size","column","index","align","variant","color","unsourced","filename","columns","disabled","displayName"],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ import { type CrmReportScope } from './report-scope';
2
+ export interface TasksCardProps {
3
+ report: CrmReportScope;
4
+ }
5
+ /**
6
+ * The task load: open, overdue and due today, and who is carrying what
7
+ * (AGL-2604).
8
+ *
9
+ * "Today" and "overdue" are decided on the LOCAL calendar day, the same day
10
+ * `taskDueState` decides them on, so the count here and the chip on the
11
+ * tasks list agree about the same task at 11 p.m. The counts are range
12
+ * queries on `dueAtMs`, which the `(visibleTo, status, dueAtMs)` index
13
+ * serves; a task with no due date is in the open count and in none of the
14
+ * dated ones.
15
+ *
16
+ * The table reads open tasks ordered by due date. An ordered read admits
17
+ * only documents that CARRY the field, so a task written without `dueAtMs`
18
+ * at all — rather than with `null`, which sorts first — is counted in the
19
+ * tile and absent from the table. The model types the field as optional,
20
+ * so the table says what it is grouped from.
21
+ */
22
+ export declare function TasksCard(props: TasksCardProps): import("react").JSX.Element;
23
+ export declare namespace TasksCard {
24
+ var displayName: string;
25
+ }
26
+ export default TasksCard;
@@ -0,0 +1,279 @@
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
+ */ 'use client';
17
+ import { _ as _extends } from "@swc/helpers/_/_extends";
18
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
19
+ import * as Aglyn from "@aglyn/aglyn";
20
+ import { AppLink, CardDisplay } from "@aglyn/shared-ui-jsx";
21
+ import { Section } from "@aglyn/shared-ui-jsx/components/measured-figures.component";
22
+ import { ScrollTable } from "@aglyn/shared-ui-jsx/components/scroll-table.component";
23
+ import { Alert, Button, Stack, TableBody, TableCell, TableHead, TableRow, Typography } from "@mui/material";
24
+ import { documentId, getCountFromServer, getDocs, limit, orderBy, query, where } from "firebase/firestore";
25
+ import { useMemo } from "react";
26
+ import { useFirestore } from "@aglyn/tenant-feature-instance";
27
+ import { ReportExport } from "./report-export.js";
28
+ import { reportFilename } from "./report-format.js";
29
+ import { reportCacheKey, scopedCollection, visibleToClause } from "./report-scope.js";
30
+ import { ReportStatTile } from "./report-stat-tile.js";
31
+ import { useAggregateRead, useWindowRead } from "./use-aggregate-read.js";
32
+ /**
33
+ * How many open tasks the by-assignee table is grouped from.
34
+ *
35
+ * The tiles are counts the server takes; the table needs each task's
36
+ * assignee and due state, so it reads the soonest-due thousand and says
37
+ * when there were more.
38
+ */ const OPEN_TASK_CEILING = 1000;
39
+ /** One `in` query's worth of member documents, for the assignee names. */ const ASSIGNEE_NAME_CEILING = 30;
40
+ /** The by-assignee table's columns, which are also the CSV's. */ const ASSIGNEE_COLUMNS = [
41
+ 'Assignee',
42
+ 'Overdue',
43
+ 'Today',
44
+ 'Upcoming',
45
+ 'No date',
46
+ 'Open'
47
+ ];
48
+ /**
49
+ * The task load: open, overdue and due today, and who is carrying what
50
+ * (AGL-2604).
51
+ *
52
+ * "Today" and "overdue" are decided on the LOCAL calendar day, the same day
53
+ * `taskDueState` decides them on, so the count here and the chip on the
54
+ * tasks list agree about the same task at 11 p.m. The counts are range
55
+ * queries on `dueAtMs`, which the `(visibleTo, status, dueAtMs)` index
56
+ * serves; a task with no due date is in the open count and in none of the
57
+ * dated ones.
58
+ *
59
+ * The table reads open tasks ordered by due date. An ordered read admits
60
+ * only documents that CARRY the field, so a task written without `dueAtMs`
61
+ * at all — rather than with `null`, which sorts first — is counted in the
62
+ * tile and absent from the table. The model types the field as optional,
63
+ * so the table says what it is grouped from.
64
+ */ export function TasksCard(props) {
65
+ const { report } = props;
66
+ const { scope, tokens, nowMs, routes } = report;
67
+ const firestore = useFirestore();
68
+ const day = useMemo(()=>Aglyn.localDayBounds(nowMs), [
69
+ nowMs
70
+ ]);
71
+ const openTasks = ()=>query(scopedCollection(firestore, scope, Aglyn.CRM_COLLECTIONS.tasks), ...visibleToClause(tokens), where('status', '==', 'open'));
72
+ const counts = useAggregateRead(()=>Promise.all([
73
+ getCountFromServer(openTasks()),
74
+ getCountFromServer(query(openTasks(), where('dueAtMs', '<', day.start))),
75
+ getCountFromServer(query(openTasks(), where('dueAtMs', '>=', day.start), where('dueAtMs', '<', day.end)))
76
+ ]).then(([open, overdue, today])=>({
77
+ open: open.data().count,
78
+ overdue: overdue.data().count,
79
+ today: today.data().count
80
+ })), [
81
+ firestore,
82
+ scope,
83
+ tokens,
84
+ day
85
+ ], {
86
+ cacheKey: reportCacheKey(report, 'tasks:counts')
87
+ });
88
+ const taskWindow = useWindowRead(()=>query(openTasks(), orderBy('dueAtMs', 'asc'), limit(OPEN_TASK_CEILING + 1)), OPEN_TASK_CEILING, [
89
+ firestore,
90
+ scope,
91
+ tokens,
92
+ nowMs
93
+ ], {
94
+ cacheKey: reportCacheKey(report, 'tasks:open')
95
+ });
96
+ const tasksStatus = taskWindow.status;
97
+ const load = useMemo(()=>{
98
+ const byAssignee = new Map();
99
+ for (const task of taskWindow.rows){
100
+ var _byAssignee_get;
101
+ const uid = task.assigneeUid || '';
102
+ const row = (_byAssignee_get = byAssignee.get(uid)) != null ? _byAssignee_get : {
103
+ uid,
104
+ overdue: 0,
105
+ today: 0,
106
+ upcoming: 0,
107
+ undated: 0,
108
+ open: 0
109
+ };
110
+ const state = Aglyn.taskDueState(task, nowMs);
111
+ if (state === 'overdue') row.overdue += 1;
112
+ else if (state === 'today') row.today += 1;
113
+ else if (state === 'upcoming') row.upcoming += 1;
114
+ else row.undated += 1;
115
+ row.open += 1;
116
+ byAssignee.set(uid, row);
117
+ }
118
+ return [
119
+ ...byAssignee.values()
120
+ ].sort((a, b)=>b.open - a.open || a.uid.localeCompare(b.uid));
121
+ }, [
122
+ taskWindow,
123
+ nowMs
124
+ ]);
125
+ /*
126
+ * The assignees' names, from their member documents — one `in` query for
127
+ * up to thirty, which is Firestore's cap on the operator and more assignees
128
+ * than a tasks list has. Anyone past it, or a member document the reader
129
+ * cannot open, shows as their id rather than blocking the table.
130
+ */ const uids = load.map((row)=>row.uid).filter(Boolean).slice(0, ASSIGNEE_NAME_CEILING);
131
+ const uidKey = uids.join(',');
132
+ const names = useAggregateRead(()=>uids.length ? getDocs(query(scopedCollection(firestore, scope, 'members'), where(documentId(), 'in', uids))).then((snapshot)=>Object.fromEntries(snapshot.docs.map((member)=>[
133
+ member.id,
134
+ String(member.get('displayName') || member.get('email') || member.id)
135
+ ]))) : Promise.resolve({}), [
136
+ firestore,
137
+ scope,
138
+ uidKey
139
+ ], {
140
+ cacheKey: reportCacheKey(report, `tasks:names:${uidKey}`)
141
+ });
142
+ const figures = counts.value;
143
+ const assigneeName = (row)=>{
144
+ var _ref;
145
+ var _names_value;
146
+ return row.uid ? (_ref = (_names_value = names.value) == null ? void 0 : _names_value[row.uid]) != null ? _ref : row.uid : 'Unassigned';
147
+ };
148
+ return /*#__PURE__*/ _jsx(CardDisplay, {
149
+ header: 'Tasks',
150
+ help: Aglyn.pluginDocsHelp('crmReports', {
151
+ anchor: '#tasks',
152
+ excerpt: 'Open tasks, how many are overdue or due today, and the open ' + 'load per assignee. Today and overdue are decided on your calendar ' + 'day, the same way the tasks list decides them.'
153
+ }),
154
+ contentGutterX: true,
155
+ contentGutterY: true,
156
+ HeaderProps: {
157
+ action: /*#__PURE__*/ _jsx(Button, _extends({
158
+ component: AppLink
159
+ }, {
160
+ componentVariant: 'naked',
161
+ nativeButton: false
162
+ }, {
163
+ href: routes.section('tasks'),
164
+ size: "small",
165
+ color: "primary",
166
+ children: 'Open tasks'
167
+ }))
168
+ },
169
+ children: /*#__PURE__*/ _jsxs(Stack, {
170
+ spacing: 2,
171
+ children: [
172
+ /*#__PURE__*/ _jsxs(Stack, {
173
+ direction: "row",
174
+ spacing: 3,
175
+ sx: {
176
+ flexWrap: 'wrap'
177
+ },
178
+ children: [
179
+ /*#__PURE__*/ _jsx(ReportStatTile, {
180
+ label: 'Open tasks',
181
+ value: figures ? figures.open.toLocaleString() : null,
182
+ note: 'counted on the server',
183
+ href: routes.section('tasks')
184
+ }),
185
+ /*#__PURE__*/ _jsx(ReportStatTile, {
186
+ label: 'Overdue',
187
+ value: figures ? figures.overdue.toLocaleString() : null,
188
+ note: 'due before today',
189
+ color: (figures == null ? void 0 : figures.overdue) ? 'error.main' : undefined,
190
+ href: routes.section('tasks')
191
+ }),
192
+ /*#__PURE__*/ _jsx(ReportStatTile, {
193
+ label: 'Due today',
194
+ value: figures ? figures.today.toLocaleString() : null,
195
+ note: 'on your calendar day',
196
+ href: routes.section('tasks')
197
+ })
198
+ ]
199
+ }),
200
+ counts.status === 'error' ? /*#__PURE__*/ _jsx(Alert, {
201
+ severity: "warning",
202
+ children: 'The task counts could not be read.'
203
+ }) : null,
204
+ /*#__PURE__*/ _jsxs(Section, {
205
+ title: 'Open tasks by assignee',
206
+ children: [
207
+ load.length ? /*#__PURE__*/ _jsxs(ScrollTable, {
208
+ size: "small",
209
+ children: [
210
+ /*#__PURE__*/ _jsx(TableHead, {
211
+ children: /*#__PURE__*/ _jsx(TableRow, {
212
+ children: ASSIGNEE_COLUMNS.map((column, index)=>/*#__PURE__*/ _jsx(TableCell, {
213
+ align: index ? 'right' : 'left',
214
+ children: column
215
+ }, column))
216
+ })
217
+ }),
218
+ /*#__PURE__*/ _jsx(TableBody, {
219
+ children: load.map((row)=>/*#__PURE__*/ _jsxs(TableRow, {
220
+ children: [
221
+ /*#__PURE__*/ _jsx(TableCell, {
222
+ children: assigneeName(row)
223
+ }),
224
+ /*#__PURE__*/ _jsx(TableCell, {
225
+ align: "right",
226
+ sx: row.overdue ? {
227
+ color: 'error.main'
228
+ } : undefined,
229
+ children: row.overdue.toLocaleString()
230
+ }),
231
+ /*#__PURE__*/ _jsx(TableCell, {
232
+ align: "right",
233
+ children: row.today.toLocaleString()
234
+ }),
235
+ /*#__PURE__*/ _jsx(TableCell, {
236
+ align: "right",
237
+ children: row.upcoming.toLocaleString()
238
+ }),
239
+ /*#__PURE__*/ _jsx(TableCell, {
240
+ align: "right",
241
+ children: row.undated.toLocaleString()
242
+ }),
243
+ /*#__PURE__*/ _jsx(TableCell, {
244
+ align: "right",
245
+ children: row.open.toLocaleString()
246
+ })
247
+ ]
248
+ }, row.uid || '$unassigned'))
249
+ })
250
+ ]
251
+ }) : /*#__PURE__*/ _jsx(Typography, {
252
+ variant: "body2",
253
+ color: "text.secondary",
254
+ children: tasksStatus === 'loading' ? 'Reading…' : 'No open tasks.'
255
+ }),
256
+ /*#__PURE__*/ _jsx(ReportExport, {
257
+ filename: reportFilename('tasks-by-assignee'),
258
+ columns: ASSIGNEE_COLUMNS,
259
+ rows: ()=>load.map((row)=>[
260
+ assigneeName(row),
261
+ row.overdue,
262
+ row.today,
263
+ row.upcoming,
264
+ row.undated,
265
+ row.open
266
+ ]),
267
+ disabled: tasksStatus !== 'success' || !load.length,
268
+ caption: taskWindow.truncated ? `Grouped from the ${OPEN_TASK_CEILING.toLocaleString()} soonest-due open tasks; the tiles are counted on the server.` : undefined
269
+ })
270
+ ]
271
+ })
272
+ ]
273
+ })
274
+ });
275
+ }
276
+ TasksCard.displayName = 'TasksCard';
277
+ export default TasksCard;
278
+
279
+ //# sourceMappingURL=tasks-card.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../../../../libs/plugins/crm/src/lib/components/reports/tasks-card.tsx"],"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'use client'\n\nimport * as Aglyn from '@aglyn/aglyn'\nimport { AppLink, CardDisplay } from '@aglyn/shared-ui-jsx'\nimport { Section } from '@aglyn/shared-ui-jsx/components/measured-figures.component'\nimport { ScrollTable } from '@aglyn/shared-ui-jsx/components/scroll-table.component'\nimport {\n Alert,\n Button,\n Stack,\n TableBody,\n TableCell,\n TableHead,\n TableRow,\n Typography,\n} from '@mui/material'\nimport {\n documentId,\n getCountFromServer,\n getDocs,\n limit,\n orderBy,\n query,\n where,\n} from 'firebase/firestore'\nimport { useMemo } from 'react'\nimport { useFirestore } from '@aglyn/tenant-feature-instance'\nimport { ReportExport } from './report-export'\nimport { reportFilename } from './report-format'\nimport {\n type CrmReportScope,\n reportCacheKey,\n scopedCollection,\n visibleToClause,\n} from './report-scope'\nimport { ReportStatTile } from './report-stat-tile'\nimport { useAggregateRead, useWindowRead } from './use-aggregate-read'\n\n/**\n * How many open tasks the by-assignee table is grouped from.\n *\n * The tiles are counts the server takes; the table needs each task's\n * assignee and due state, so it reads the soonest-due thousand and says\n * when there were more.\n */\nconst OPEN_TASK_CEILING = 1000\n/** One `in` query's worth of member documents, for the assignee names. */\nconst ASSIGNEE_NAME_CEILING = 30\n\ntype TaskRow = Aglyn.CrmTask & { $id: string }\n\n/** The by-assignee table's columns, which are also the CSV's. */\nconst ASSIGNEE_COLUMNS = ['Assignee', 'Overdue', 'Today', 'Upcoming', 'No date', 'Open'] as const\n\ninterface AssigneeLoad {\n uid: string\n overdue: number\n today: number\n upcoming: number\n undated: number\n open: number\n}\n\nexport interface TasksCardProps {\n report: CrmReportScope\n}\n\n/**\n * The task load: open, overdue and due today, and who is carrying what\n * (AGL-2604).\n *\n * \"Today\" and \"overdue\" are decided on the LOCAL calendar day, the same day\n * `taskDueState` decides them on, so the count here and the chip on the\n * tasks list agree about the same task at 11 p.m. The counts are range\n * queries on `dueAtMs`, which the `(visibleTo, status, dueAtMs)` index\n * serves; a task with no due date is in the open count and in none of the\n * dated ones.\n *\n * The table reads open tasks ordered by due date. An ordered read admits\n * only documents that CARRY the field, so a task written without `dueAtMs`\n * at all — rather than with `null`, which sorts first — is counted in the\n * tile and absent from the table. The model types the field as optional,\n * so the table says what it is grouped from.\n */\nexport function TasksCard(props: TasksCardProps) {\n const { report } = props\n const { scope, tokens, nowMs, routes } = report\n const firestore = useFirestore()\n const day = useMemo(() => Aglyn.localDayBounds(nowMs), [nowMs])\n\n const openTasks = () =>\n query(\n scopedCollection(firestore, scope, Aglyn.CRM_COLLECTIONS.tasks),\n ...visibleToClause(tokens),\n where('status', '==', 'open'),\n )\n\n const counts = useAggregateRead(\n () =>\n Promise.all([\n getCountFromServer(openTasks()),\n getCountFromServer(query(openTasks(), where('dueAtMs', '<', day.start))),\n getCountFromServer(\n query(\n openTasks(),\n where('dueAtMs', '>=', day.start),\n where('dueAtMs', '<', day.end),\n ),\n ),\n ]).then(([open, overdue, today]) => ({\n open: open.data().count,\n overdue: overdue.data().count,\n today: today.data().count,\n })),\n [firestore, scope, tokens, day],\n { cacheKey: reportCacheKey(report, 'tasks:counts') },\n )\n\n const taskWindow = useWindowRead<TaskRow>(\n () =>\n query(\n openTasks(),\n orderBy('dueAtMs', 'asc'),\n limit(OPEN_TASK_CEILING + 1),\n ),\n OPEN_TASK_CEILING,\n [firestore, scope, tokens, nowMs],\n { cacheKey: reportCacheKey(report, 'tasks:open') },\n )\n const tasksStatus = taskWindow.status\n\n const load = useMemo(() => {\n const byAssignee = new Map<string, AssigneeLoad>()\n for (const task of taskWindow.rows) {\n const uid = task.assigneeUid || ''\n const row = byAssignee.get(uid) ?? {\n uid,\n overdue: 0,\n today: 0,\n upcoming: 0,\n undated: 0,\n open: 0,\n }\n const state = Aglyn.taskDueState(task, nowMs)\n if (state === 'overdue') row.overdue += 1\n else if (state === 'today') row.today += 1\n else if (state === 'upcoming') row.upcoming += 1\n else row.undated += 1\n row.open += 1\n byAssignee.set(uid, row)\n }\n return [...byAssignee.values()].sort(\n (a, b) => b.open - a.open || a.uid.localeCompare(b.uid),\n )\n }, [taskWindow, nowMs])\n\n /*\n * The assignees' names, from their member documents — one `in` query for\n * up to thirty, which is Firestore's cap on the operator and more assignees\n * than a tasks list has. Anyone past it, or a member document the reader\n * cannot open, shows as their id rather than blocking the table.\n */\n const uids = load.map((row) => row.uid).filter(Boolean).slice(0, ASSIGNEE_NAME_CEILING)\n const uidKey = uids.join(',')\n const names = useAggregateRead<Record<string, string>>(\n () =>\n uids.length\n ? getDocs(\n query(\n scopedCollection(firestore, scope, 'members'),\n where(documentId(), 'in', uids),\n ),\n ).then((snapshot) =>\n Object.fromEntries(\n snapshot.docs.map((member) => [\n member.id,\n String(member.get('displayName') || member.get('email') || member.id),\n ]),\n ),\n )\n : Promise.resolve({}),\n [firestore, scope, uidKey],\n { cacheKey: reportCacheKey(report, `tasks:names:${uidKey}`) },\n )\n\n const figures = counts.value\n const assigneeName = (row: AssigneeLoad): string =>\n row.uid ? names.value?.[row.uid] ?? row.uid : 'Unassigned'\n return (\n <CardDisplay\n header={'Tasks'}\n help={Aglyn.pluginDocsHelp('crmReports', {\n anchor: '#tasks',\n excerpt:\n 'Open tasks, how many are overdue or due today, and the open ' +\n 'load per assignee. Today and overdue are decided on your calendar ' +\n 'day, the same way the tasks list decides them.',\n })}\n contentGutterX\n contentGutterY\n HeaderProps={{\n action: (\n <Button\n component={AppLink as any}\n {...({ componentVariant: 'naked', nativeButton: false } as any)}\n href={routes.section('tasks')}\n size=\"small\"\n color=\"primary\"\n >\n {'Open tasks'}\n </Button>\n ),\n }}\n >\n <Stack spacing={2}>\n <Stack direction=\"row\" spacing={3} sx={{ flexWrap: 'wrap' }}>\n <ReportStatTile\n label={'Open tasks'}\n value={figures ? figures.open.toLocaleString() : null}\n note={'counted on the server'}\n href={routes.section('tasks')}\n />\n <ReportStatTile\n label={'Overdue'}\n value={figures ? figures.overdue.toLocaleString() : null}\n note={'due before today'}\n color={figures?.overdue ? 'error.main' : undefined}\n href={routes.section('tasks')}\n />\n <ReportStatTile\n label={'Due today'}\n value={figures ? figures.today.toLocaleString() : null}\n note={'on your calendar day'}\n href={routes.section('tasks')}\n />\n </Stack>\n {counts.status === 'error' ? (\n <Alert severity=\"warning\">{'The task counts could not be read.'}</Alert>\n ) : null}\n <Section title={'Open tasks by assignee'}>\n {load.length ? (\n <ScrollTable size=\"small\">\n <TableHead>\n <TableRow>\n {ASSIGNEE_COLUMNS.map((column, index) => (\n <TableCell key={column} align={index ? 'right' : 'left'}>\n {column}\n </TableCell>\n ))}\n </TableRow>\n </TableHead>\n <TableBody>\n {load.map((row) => (\n <TableRow key={row.uid || '$unassigned'}>\n <TableCell>{assigneeName(row)}</TableCell>\n <TableCell\n align=\"right\"\n sx={row.overdue ? { color: 'error.main' } : undefined}\n >\n {row.overdue.toLocaleString()}\n </TableCell>\n <TableCell align=\"right\">{row.today.toLocaleString()}</TableCell>\n <TableCell align=\"right\">{row.upcoming.toLocaleString()}</TableCell>\n <TableCell align=\"right\">{row.undated.toLocaleString()}</TableCell>\n <TableCell align=\"right\">{row.open.toLocaleString()}</TableCell>\n </TableRow>\n ))}\n </TableBody>\n </ScrollTable>\n ) : (\n <Typography variant=\"body2\" color=\"text.secondary\">\n {tasksStatus === 'loading' ? 'Reading…' : 'No open tasks.'}\n </Typography>\n )}\n <ReportExport\n filename={reportFilename('tasks-by-assignee')}\n columns={ASSIGNEE_COLUMNS}\n rows={() =>\n load.map((row) => [\n assigneeName(row),\n row.overdue,\n row.today,\n row.upcoming,\n row.undated,\n row.open,\n ])\n }\n disabled={tasksStatus !== 'success' || !load.length}\n caption={\n taskWindow.truncated\n ? `Grouped from the ${OPEN_TASK_CEILING.toLocaleString()} soonest-due open tasks; the tiles are counted on the server.`\n : undefined\n }\n />\n </Section>\n </Stack>\n </CardDisplay>\n )\n}\nTasksCard.displayName = 'TasksCard'\n\nexport default TasksCard\n"],"names":["Aglyn","AppLink","CardDisplay","Section","ScrollTable","Alert","Button","Stack","TableBody","TableCell","TableHead","TableRow","Typography","documentId","getCountFromServer","getDocs","limit","orderBy","query","where","useMemo","useFirestore","ReportExport","reportFilename","reportCacheKey","scopedCollection","visibleToClause","ReportStatTile","useAggregateRead","useWindowRead","OPEN_TASK_CEILING","ASSIGNEE_NAME_CEILING","ASSIGNEE_COLUMNS","TasksCard","props","report","scope","tokens","nowMs","routes","firestore","day","localDayBounds","openTasks","CRM_COLLECTIONS","tasks","counts","Promise","all","start","end","then","open","overdue","today","data","count","cacheKey","taskWindow","tasksStatus","status","load","byAssignee","Map","task","rows","uid","assigneeUid","row","get","upcoming","undated","state","taskDueState","set","values","sort","a","b","localeCompare","uids","map","filter","Boolean","slice","uidKey","join","names","length","snapshot","Object","fromEntries","docs","member","id","String","resolve","figures","value","assigneeName","header","help","pluginDocsHelp","anchor","excerpt","contentGutterX","contentGutterY","HeaderProps","action","component","componentVariant","nativeButton","href","section","size","color","spacing","direction","sx","flexWrap","label","toLocaleString","note","undefined","severity","title","column","index","align","variant","filename","columns","disabled","caption","truncated","displayName"],"mappings":"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"}