@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/hooks/use-crm-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'use client'\n\nimport {\n type ConsentGroup,\n type ConsolePluginPageProps,\n consentGroupForHost,\n crmReadTokens,\n crmScopeTokens,\n type ScopeToken,\n} from '@aglyn/aglyn'\nimport { useOrgDataScope } from '@aglyn/tenant-feature-instance'\nimport { type QueryConstraint, where } from 'firebase/firestore'\nimport { useMemo } from 'react'\nimport { useCrmOrgMount } from './use-crm-org-mount'\n\n/**\n * The org document as a CRM surface receives it: the shell's typed billing\n * projection on a page, or the plain record a card was handed. Read as a\n * record at the one seam below, so no component casts it itself.\n */\nexport type CrmOrgDoc =\n | ConsolePluginPageProps['org']\n | Record<string, unknown>\n | null\n | undefined\n\n/** Where a CRM surface is mounted: under one site, or over the whole org. */\nexport type CrmScopeLevel = 'site' | 'org'\n\nexport interface CrmScope {\n /** The org data root, or `null` until the org lookup settles or when there is none. */\n scope: readonly ['orgs', string] | null\n /** The owning org, or null while the lookup runs or when there is none. */\n orgId: string | null\n /** Whether the org lookup has settled — `orgId` null after this means no org. */\n ready: boolean\n /** Under a site, or at the organization level (AGL-2630). */\n level: CrmScopeLevel\n /** The mounted site, or `null` at the organization level. */\n hostId: string | null\n /**\n * The controller this surface is being viewed as, or `null` at the org\n * level, where there is no one viewing site: a cross-holder reader\n * resolves each contact's own facet instead (`contactPrimaryGroup`).\n */\n consentGroup: ConsentGroup | null\n /**\n * What this viewer may LIST — every listener's `array-contains-any`\n * predicate, capped at what the operator accepts — or `null` at the org\n * level, where an org-wide member's listeners carry NO scope clause: the\n * rules' `canReadScoped()` short-circuits on `isOrgWideMember()`, so the\n * clause would only ever narrow what the reader is already allowed. Hand\n * it to {@link crmVisibleToClause}, which spells both cases. Stable across\n * renders for the same org and site, so it can sit in a query's\n * dependency list.\n */\n visibleTo: readonly ScopeToken[] | null\n /**\n * The site a record this viewer CREATES is captured by: the mounted site,\n * or at the org level the site the reader picked (`null` until they\n * have). A create must hold until this is known — the tokens below are\n * empty without it, and a record stamped with none is visible to nobody.\n */\n createHostId: string | null\n /** The consent group of {@link createHostId} — what a create records consent for. */\n createGroup: ConsentGroup | null\n /** What a record this viewer CREATES is stamped with; empty until {@link createHostId} is known. */\n createTokens: readonly ScopeToken[]\n}\n\nconst NO_TOKENS: readonly ScopeToken[] = Object.freeze([])\n\n/**\n * The scope facts every CRM surface needs, resolved once (AGL-2597, one\n * hook since AGL-2614, two levels since AGL-2630).\n *\n * A CRM surface — a list, a record page, a drawer, a card on somebody\n * else's page — resolves its consent group, builds the token list its\n * listener filters on, builds the tokens a create stamps, and looks up the\n * org root. Every section needs the same answers, and for a while the deals\n * had a hook of their own that answered them under different names\n * (`readTokens` for `visibleTo`), which is two chances to filter by one set\n * of tokens and stamp with another. This is the one place the expression\n * lives: a surface that spelled its own could omit the `'org'` token and\n * stop listing the org-wide records the rules would have let it read.\n *\n * ## Two levels, one call\n *\n * Under a site, `hostId` names it and everything follows from the org\n * document and that id, as it always has. At the ORGANIZATION level the\n * hub hands every surface `hostId: null`, and the org comes from the mount\n * the hub published (`useCrmOrgMount`): the org root is known at once,\n * reads are unscoped, and the site a create stamps from is the one the\n * reader picked. A surface written against `{ scope, visibleTo,\n * createTokens }` serves both levels without knowing which it is on — the\n * two differences it cannot ignore are that `visibleTo` and `consentGroup`\n * are `null` at the org level, and both are typed to say so.\n *\n * `visibleTo` and `createTokens` are different questions with different\n * answers. The first is the union of everything this viewer may see; the\n * second is where a new record lands, which `crmScopeTokens` decides from\n * the org's default and is narrower — a group of one site creates for that\n * site, and reads the org-wide rows beside its own.\n *\n * Pure over the org document the shell already passed, so it costs no read;\n * only the org lookup behind `useOrgDataScope` is asynchronous, and `ready`\n * is how a surface tells \"not yet\" from \"no org\".\n */\nexport function useCrmScope(props: {\n hostId: string | null | undefined\n org?: CrmOrgDoc\n}): CrmScope {\n const hostId = props.hostId || null\n const org = (props.org ?? null) as Record<string, unknown> | null\n const mount = useCrmOrgMount()\n // Under a site the org is looked up from the host index; at the org level\n // it is the mount's, known at once. A `null` host with no mount is a\n // surface mounted nowhere, and resolves to no org rather than guessing.\n const { scope, orgId, ready } = useOrgDataScope(\n hostId ? { hostId } : { orgId: mount?.orgId },\n )\n const level: CrmScopeLevel = hostId ? 'site' : 'org'\n const consentGroup = useMemo(\n () => (hostId ? consentGroupForHost(org, hostId) : null),\n [org, hostId],\n )\n const visibleTo = useMemo(\n () => (consentGroup ? crmReadTokens(consentGroup) : null),\n [consentGroup],\n )\n const createHostId = hostId ?? mount?.createHostId ?? null\n const createGroup = useMemo(\n () => (createHostId ? consentGroupForHost(org, createHostId) : null),\n [org, createHostId],\n )\n const createTokens = useMemo(\n () => (createGroup ? crmScopeTokens(org, createGroup) : NO_TOKENS),\n [org, createGroup],\n )\n return useMemo(\n () => ({\n scope,\n orgId,\n ready,\n level,\n hostId,\n consentGroup,\n visibleTo,\n createHostId,\n createGroup,\n createTokens,\n }),\n [\n scope,\n orgId,\n ready,\n level,\n hostId,\n consentGroup,\n visibleTo,\n createHostId,\n createGroup,\n createTokens,\n ],\n )\n}\n\n/**\n * The scope clause a CRM listener carries, spelled once for both levels\n * (AGL-2630).\n *\n * Under a site: `where('visibleTo', 'array-contains-any', tokens)`, the\n * predicate the rules evaluate with `hasAny`, which is what makes a\n * filtered query provable per document. At the org level: NOTHING — the\n * reader is an org-wide member, the rules admit them to every row, and a\n * query that kept the clause would need the org's whole site list on it\n * and still miss a site the list did not carry. Spread into the query, so\n * the two cases are one line at every listener: `...crmVisibleToClause(\n * scope.visibleTo)`.\n *\n * A query that drops an `array-contains-any` may need a composite index\n * the scoped form did not: the equality and range clauses beside it stay,\n * and Firestore composes them on their own. The org-level entries live in\n * `cloud/firebase-firestore.indexes.json` beside their scoped twins.\n */\nexport function crmVisibleToClause(\n visibleTo: readonly ScopeToken[] | readonly string[] | null | undefined,\n): QueryConstraint[] {\n if (!visibleTo) return []\n return [where('visibleTo', 'array-contains-any', [...visibleTo])]\n}\n\n/**\n * Whether a listener that filters on `visibleTo` has anything to ask for:\n * `true` at the org level (no clause is a complete question), and under a\n * site only when the token list is non-empty — an `array-contains-any`\n * over nothing is a query Firestore refuses.\n */\nexport function crmScopeListable(\n visibleTo: readonly ScopeToken[] | readonly string[] | null | undefined,\n): boolean {\n return visibleTo === null || visibleTo === undefined || visibleTo.length > 0\n}\n\nexport default useCrmScope\n"],"names":["consentGroupForHost","crmReadTokens","crmScopeTokens","useOrgDataScope","where","useMemo","useCrmOrgMount","NO_TOKENS","Object","freeze","useCrmScope","props","hostId","org","mount","scope","orgId","ready","level","consentGroup","visibleTo","createHostId","createGroup","createTokens","crmVisibleToClause","crmScopeListable","undefined","length"],"mappings":"AAAA;;;;;;;;;;;;;;;CAeC,GACD;AAEA,SAGEA,mBAAmB,EACnBC,aAAa,EACbC,cAAc,QAET,eAAc;AACrB,SAASC,eAAe,QAAQ,iCAAgC;AAChE,SAA+BC,KAAK,QAAQ,qBAAoB;AAChE,SAASC,OAAO,QAAQ,QAAO;AAC/B,SAASC,cAAc,QAAQ,yBAAqB;AAyDpD,MAAMC,YAAmCC,OAAOC,MAAM,CAAC,EAAE;AAEzD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAmCC,GACD,OAAO,SAASC,YAAYC,KAG3B;QAEcA,YAiBQC;IAlBrB,MAAMA,SAASD,MAAMC,MAAM,IAAI;IAC/B,MAAMC,OAAOF,aAAAA,MAAME,GAAG,YAATF,aAAa;IAC1B,MAAMG,QAAQR;IACd,0EAA0E;IAC1E,qEAAqE;IACrE,wEAAwE;IACxE,MAAM,EAAES,KAAK,EAAEC,KAAK,EAAEC,KAAK,EAAE,GAAGd,gBAC9BS,SAAS;QAAEA;IAAO,IAAI;QAAEI,KAAK,EAAEF,yBAAAA,MAAOE,KAAK;IAAC;IAE9C,MAAME,QAAuBN,SAAS,SAAS;IAC/C,MAAMO,eAAed,QACnB,IAAOO,SAASZ,oBAAoBa,KAAKD,UAAU,MACnD;QAACC;QAAKD;KAAO;IAEf,MAAMQ,YAAYf,QAChB,IAAOc,eAAelB,cAAckB,gBAAgB,MACpD;QAACA;KAAa;IAEhB,MAAME,gBAAeT,OAAAA,iBAAAA,SAAUE,yBAAAA,MAAOO,YAAY,YAA7BT,OAAiC;IACtD,MAAMU,cAAcjB,QAClB,IAAOgB,eAAerB,oBAAoBa,KAAKQ,gBAAgB,MAC/D;QAACR;QAAKQ;KAAa;IAErB,MAAME,eAAelB,QACnB,IAAOiB,cAAcpB,eAAeW,KAAKS,eAAef,WACxD;QAACM;QAAKS;KAAY;IAEpB,OAAOjB,QACL,IAAO,CAAA;YACLU;YACAC;YACAC;YACAC;YACAN;YACAO;YACAC;YACAC;YACAC;YACAC;QACF,CAAA,GACA;QACER;QACAC;QACAC;QACAC;QACAN;QACAO;QACAC;QACAC;QACAC;QACAC;KACD;AAEL;AAEA;;;;;;;;;;;;;;;;;CAiBC,GACD,OAAO,SAASC,mBACdJ,SAAuE;IAEvE,IAAI,CAACA,WAAW,OAAO,EAAE;IACzB,OAAO;QAAChB,MAAM,aAAa,sBAAsB;eAAIgB;SAAU;KAAE;AACnE;AAEA;;;;;CAKC,GACD,OAAO,SAASK,iBACdL,SAAuE;IAEvE,OAAOA,cAAc,QAAQA,cAAcM,aAAaN,UAAUO,MAAM,GAAG;AAC7E;AAEA,eAAejB,YAAW"}
@@ -0,0 +1,85 @@
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';
18
+ import { type CrmTaskView } from '../model/task-views';
19
+ /** A task as the console lists it: the document plus its id. */
20
+ export type CrmTaskRow = CrmTask & {
21
+ $id: string;
22
+ };
23
+ /**
24
+ * The reader's clock, refreshed once a minute (AGL-2599).
25
+ *
26
+ * "Overdue" and "today" are computed at read time against this value, so a
27
+ * tab left open across midnight repaints yesterday's work red without a
28
+ * reload. A minute is coarse enough that the re-render is invisible and fine
29
+ * enough that a task due at 9:00 does not read as upcoming at 9:05.
30
+ */
31
+ export declare function useNowMs(): number;
32
+ export interface CrmTaskListResult {
33
+ tasks: CrmTaskRow[];
34
+ status: 'loading' | 'success' | 'error';
35
+ /** The rows are unconfirmed by the server — what a guarded write reads. */
36
+ fromCache: boolean;
37
+ /** The window filled up; there are tasks this view is not showing. */
38
+ truncated: boolean;
39
+ scope: readonly [string, string] | null;
40
+ orgId: string | null | undefined;
41
+ /** The reader's tokens, or `null` at the organization level — no clause (AGL-2630). */
42
+ readTokens: readonly string[] | null;
43
+ }
44
+ /**
45
+ * One view of the tasks section as a live, bounded listener.
46
+ *
47
+ * The plan comes from `crmTaskViewPlan`, so the hook holds no opinion about
48
+ * what "today" means; it translates a plan into constraints in the order the
49
+ * `crmTasks` indexes are declared and caps the window. "My tasks" opens no
50
+ * listener at all until the reader's uid is known — a query for
51
+ * `assigneeUid == ''` would be a real read that could only answer nothing.
52
+ */
53
+ export declare function useCrmTaskList(options: {
54
+ /** The site the list is read under, or `null` at the organization level. */
55
+ hostId: string | null;
56
+ org?: Record<string, unknown> | null;
57
+ view: CrmTaskView;
58
+ uid: string | null | undefined;
59
+ nowMs: number;
60
+ }): CrmTaskListResult;
61
+ /**
62
+ * How many of one record's tasks a card reads. A person with more than fifty
63
+ * open tasks about one contact has a different problem than a short list.
64
+ */
65
+ export declare const CRM_RECORD_TASK_LIMIT = 50;
66
+ /** Which record a task list is FOR — exactly one of the three. */
67
+ export interface CrmRecordRef {
68
+ contactId?: string;
69
+ companyId?: string;
70
+ dealId?: string;
71
+ }
72
+ /**
73
+ * The tasks that hang off one contact, company or deal, open and done
74
+ * together, soonest due first.
75
+ *
76
+ * Rides the per-record indexes — `(visibleTo, contactId, dueAtMs)` and its
77
+ * two siblings — with no status clause, because the card shows the open ones
78
+ * and counts the rest, and two listeners for one short list is one too many.
79
+ */
80
+ export declare function useCrmRecordTasks(options: {
81
+ /** The site the record is read under, or `null` at the organization level. */
82
+ hostId: string | null;
83
+ org?: Record<string, unknown> | null;
84
+ record: CrmRecordRef;
85
+ }): CrmTaskListResult;
@@ -0,0 +1,153 @@
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 { CRM_COLLECTIONS } from "@aglyn/aglyn";
17
+ import { useFirestore, useFirestoreCollection } from "@aglyn/tenant-feature-instance";
18
+ import { collection, limit, orderBy, query, where } from "firebase/firestore";
19
+ import { useEffect, useMemo, useState } from "react";
20
+ import { CRM_TASK_VIEW_LIMIT, crmTaskViewPlan, orderTaskRows } from "../model/task-views.js";
21
+ import { crmVisibleToClause, useCrmScope } from "./use-crm-scope.js";
22
+ /**
23
+ * The reader's clock, refreshed once a minute (AGL-2599).
24
+ *
25
+ * "Overdue" and "today" are computed at read time against this value, so a
26
+ * tab left open across midnight repaints yesterday's work red without a
27
+ * reload. A minute is coarse enough that the re-render is invisible and fine
28
+ * enough that a task due at 9:00 does not read as upcoming at 9:05.
29
+ */ export function useNowMs() {
30
+ const [nowMs, setNowMs] = useState(()=>Date.now());
31
+ useEffect(()=>{
32
+ const timer = setInterval(()=>setNowMs(Date.now()), 60000);
33
+ return ()=>clearInterval(timer);
34
+ }, []);
35
+ return nowMs;
36
+ }
37
+ /**
38
+ * One view of the tasks section as a live, bounded listener.
39
+ *
40
+ * The plan comes from `crmTaskViewPlan`, so the hook holds no opinion about
41
+ * what "today" means; it translates a plan into constraints in the order the
42
+ * `crmTasks` indexes are declared and caps the window. "My tasks" opens no
43
+ * listener at all until the reader's uid is known — a query for
44
+ * `assigneeUid == ''` would be a real read that could only answer nothing.
45
+ */ export function useCrmTaskList(options) {
46
+ var _ref;
47
+ const { hostId, org, view, uid, nowMs } = options;
48
+ const firestore = useFirestore();
49
+ // The org root and the reader's tokens from the one scope hook (AGL-2614)
50
+ // — the same expression the contacts list runs, so a task listed beside a
51
+ // contact is scoped by exactly the predicate that admitted the contact.
52
+ const { scope, orgId, visibleTo: readTokens } = useCrmScope({
53
+ hostId,
54
+ org
55
+ });
56
+ const plan = useMemo(()=>crmTaskViewPlan(view, {
57
+ nowMs,
58
+ uid
59
+ }), [
60
+ view,
61
+ nowMs,
62
+ uid
63
+ ]);
64
+ const { data, status, fromCache } = useFirestoreCollection(()=>{
65
+ if (!scope) return null;
66
+ if (plan.assigneeUid !== undefined && !plan.assigneeUid) return null;
67
+ const constraints = [
68
+ ...crmVisibleToClause(readTokens),
69
+ where('status', '==', plan.status)
70
+ ];
71
+ if (plan.assigneeUid) {
72
+ constraints.push(where('assigneeUid', '==', plan.assigneeUid));
73
+ }
74
+ if (plan.dueFrom !== undefined) {
75
+ constraints.push(where('dueAtMs', '>=', plan.dueFrom));
76
+ }
77
+ if (plan.dueBefore !== undefined) {
78
+ constraints.push(where('dueAtMs', '<', plan.dueBefore));
79
+ }
80
+ return query(collection(firestore, scope[0], scope[1], CRM_COLLECTIONS.tasks), ...constraints, orderBy('dueAtMs', plan.direction), limit(CRM_TASK_VIEW_LIMIT));
81
+ }, [
82
+ firestore,
83
+ scope,
84
+ readTokens,
85
+ plan.status,
86
+ plan.assigneeUid,
87
+ plan.dueFrom,
88
+ plan.dueBefore,
89
+ plan.direction
90
+ ], {
91
+ idField: '$id'
92
+ });
93
+ const tasks = useMemo(()=>orderTaskRows(data != null ? data : []), [
94
+ data
95
+ ]);
96
+ return {
97
+ tasks,
98
+ status,
99
+ fromCache,
100
+ truncated: ((_ref = data == null ? void 0 : data.length) != null ? _ref : 0) >= CRM_TASK_VIEW_LIMIT,
101
+ scope,
102
+ orgId,
103
+ readTokens
104
+ };
105
+ }
106
+ /**
107
+ * How many of one record's tasks a card reads. A person with more than fifty
108
+ * open tasks about one contact has a different problem than a short list.
109
+ */ export const CRM_RECORD_TASK_LIMIT = 50;
110
+ /**
111
+ * The tasks that hang off one contact, company or deal, open and done
112
+ * together, soonest due first.
113
+ *
114
+ * Rides the per-record indexes — `(visibleTo, contactId, dueAtMs)` and its
115
+ * two siblings — with no status clause, because the card shows the open ones
116
+ * and counts the rest, and two listeners for one short list is one too many.
117
+ */ export function useCrmRecordTasks(options) {
118
+ var _ref;
119
+ const { hostId, org, record } = options;
120
+ const firestore = useFirestore();
121
+ const { scope, orgId, visibleTo: readTokens } = useCrmScope({
122
+ hostId,
123
+ org
124
+ });
125
+ const field = record.contactId ? 'contactId' : record.companyId ? 'companyId' : record.dealId ? 'dealId' : null;
126
+ const id = field ? record[field] : undefined;
127
+ const { data, status, fromCache } = useFirestoreCollection(()=>{
128
+ if (!scope || !field || !id) return null;
129
+ return query(collection(firestore, scope[0], scope[1], CRM_COLLECTIONS.tasks), ...crmVisibleToClause(readTokens), where(field, '==', id), orderBy('dueAtMs', 'asc'), limit(CRM_RECORD_TASK_LIMIT));
130
+ }, [
131
+ firestore,
132
+ scope,
133
+ readTokens,
134
+ field,
135
+ id
136
+ ], {
137
+ idField: '$id'
138
+ });
139
+ const tasks = useMemo(()=>orderTaskRows(data != null ? data : []), [
140
+ data
141
+ ]);
142
+ return {
143
+ tasks,
144
+ status,
145
+ fromCache,
146
+ truncated: ((_ref = data == null ? void 0 : data.length) != null ? _ref : 0) >= CRM_RECORD_TASK_LIMIT,
147
+ scope,
148
+ orgId,
149
+ readTokens
150
+ };
151
+ }
152
+
153
+ //# sourceMappingURL=use-crm-tasks.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../../../libs/plugins/crm/src/lib/hooks/use-crm-tasks.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 { CRM_COLLECTIONS, type CrmTask } from '@aglyn/aglyn'\nimport {\n useFirestore,\n useFirestoreCollection,\n} from '@aglyn/tenant-feature-instance'\nimport {\n collection,\n limit,\n orderBy,\n query,\n type QueryConstraint,\n where,\n} from 'firebase/firestore'\nimport { useEffect, useMemo, useState } from 'react'\nimport {\n CRM_TASK_VIEW_LIMIT,\n type CrmTaskView,\n crmTaskViewPlan,\n orderTaskRows,\n} from '../model/task-views'\nimport { crmVisibleToClause, useCrmScope } from './use-crm-scope'\n\n/** A task as the console lists it: the document plus its id. */\nexport type CrmTaskRow = CrmTask & { $id: string }\n\n/**\n * The reader's clock, refreshed once a minute (AGL-2599).\n *\n * \"Overdue\" and \"today\" are computed at read time against this value, so a\n * tab left open across midnight repaints yesterday's work red without a\n * reload. A minute is coarse enough that the re-render is invisible and fine\n * enough that a task due at 9:00 does not read as upcoming at 9:05.\n */\nexport function useNowMs(): number {\n const [nowMs, setNowMs] = useState(() => Date.now())\n useEffect(() => {\n const timer = setInterval(() => setNowMs(Date.now()), 60_000)\n return () => clearInterval(timer)\n }, [])\n return nowMs\n}\n\nexport interface CrmTaskListResult {\n tasks: CrmTaskRow[]\n status: 'loading' | 'success' | 'error'\n /** The rows are unconfirmed by the server — what a guarded write reads. */\n fromCache: boolean\n /** The window filled up; there are tasks this view is not showing. */\n truncated: boolean\n scope: readonly [string, string] | null\n orgId: string | null | undefined\n /** The reader's tokens, or `null` at the organization level — no clause (AGL-2630). */\n readTokens: readonly string[] | null\n}\n\n/**\n * One view of the tasks section as a live, bounded listener.\n *\n * The plan comes from `crmTaskViewPlan`, so the hook holds no opinion about\n * what \"today\" means; it translates a plan into constraints in the order the\n * `crmTasks` indexes are declared and caps the window. \"My tasks\" opens no\n * listener at all until the reader's uid is known — a query for\n * `assigneeUid == ''` would be a real read that could only answer nothing.\n */\nexport function useCrmTaskList(options: {\n /** The site the list is read under, or `null` at the organization level. */\n hostId: string | null\n org?: Record<string, unknown> | null\n view: CrmTaskView\n uid: string | null | undefined\n nowMs: number\n}): CrmTaskListResult {\n const { hostId, org, view, uid, nowMs } = options\n const firestore = useFirestore()\n // The org root and the reader's tokens from the one scope hook (AGL-2614)\n // — the same expression the contacts list runs, so a task listed beside a\n // contact is scoped by exactly the predicate that admitted the contact.\n const { scope, orgId, visibleTo: readTokens } = useCrmScope({ hostId, org })\n const plan = useMemo(\n () => crmTaskViewPlan(view, { nowMs, uid }),\n [view, nowMs, uid],\n )\n const { data, status, fromCache } = useFirestoreCollection<CrmTaskRow>(\n () => {\n if (!scope) return null\n if (plan.assigneeUid !== undefined && !plan.assigneeUid) return null\n const constraints: QueryConstraint[] = [\n ...crmVisibleToClause(readTokens),\n where('status', '==', plan.status),\n ]\n if (plan.assigneeUid) {\n constraints.push(where('assigneeUid', '==', plan.assigneeUid))\n }\n if (plan.dueFrom !== undefined) {\n constraints.push(where('dueAtMs', '>=', plan.dueFrom))\n }\n if (plan.dueBefore !== undefined) {\n constraints.push(where('dueAtMs', '<', plan.dueBefore))\n }\n return query(\n collection(firestore, scope[0], scope[1], CRM_COLLECTIONS.tasks),\n ...constraints,\n orderBy('dueAtMs', plan.direction),\n limit(CRM_TASK_VIEW_LIMIT),\n )\n },\n [\n firestore,\n scope,\n readTokens,\n plan.status,\n plan.assigneeUid,\n plan.dueFrom,\n plan.dueBefore,\n plan.direction,\n ],\n { idField: '$id' },\n )\n const tasks = useMemo(() => orderTaskRows(data ?? []), [data])\n return {\n tasks,\n status,\n fromCache,\n truncated: (data?.length ?? 0) >= CRM_TASK_VIEW_LIMIT,\n scope,\n orgId,\n readTokens,\n }\n}\n\n/**\n * How many of one record's tasks a card reads. A person with more than fifty\n * open tasks about one contact has a different problem than a short list.\n */\nexport const CRM_RECORD_TASK_LIMIT = 50\n\n/** Which record a task list is FOR — exactly one of the three. */\nexport interface CrmRecordRef {\n contactId?: string\n companyId?: string\n dealId?: string\n}\n\n/**\n * The tasks that hang off one contact, company or deal, open and done\n * together, soonest due first.\n *\n * Rides the per-record indexes — `(visibleTo, contactId, dueAtMs)` and its\n * two siblings — with no status clause, because the card shows the open ones\n * and counts the rest, and two listeners for one short list is one too many.\n */\nexport function useCrmRecordTasks(options: {\n /** The site the record is read under, or `null` at the organization level. */\n hostId: string | null\n org?: Record<string, unknown> | null\n record: CrmRecordRef\n}): CrmTaskListResult {\n const { hostId, org, record } = options\n const firestore = useFirestore()\n const { scope, orgId, visibleTo: readTokens } = useCrmScope({ hostId, org })\n const field = record.contactId\n ? 'contactId'\n : record.companyId\n ? 'companyId'\n : record.dealId\n ? 'dealId'\n : null\n const id = field ? record[field] : undefined\n const { data, status, fromCache } = useFirestoreCollection<CrmTaskRow>(\n () => {\n if (!scope || !field || !id) return null\n return query(\n collection(firestore, scope[0], scope[1], CRM_COLLECTIONS.tasks),\n ...crmVisibleToClause(readTokens),\n where(field, '==', id),\n orderBy('dueAtMs', 'asc'),\n limit(CRM_RECORD_TASK_LIMIT),\n )\n },\n [firestore, scope, readTokens, field, id],\n { idField: '$id' },\n )\n const tasks = useMemo(() => orderTaskRows(data ?? []), [data])\n return {\n tasks,\n status,\n fromCache,\n truncated: (data?.length ?? 0) >= CRM_RECORD_TASK_LIMIT,\n scope,\n orgId,\n readTokens,\n }\n}\n"],"names":["CRM_COLLECTIONS","useFirestore","useFirestoreCollection","collection","limit","orderBy","query","where","useEffect","useMemo","useState","CRM_TASK_VIEW_LIMIT","crmTaskViewPlan","orderTaskRows","crmVisibleToClause","useCrmScope","useNowMs","nowMs","setNowMs","Date","now","timer","setInterval","clearInterval","useCrmTaskList","options","hostId","org","view","uid","firestore","scope","orgId","visibleTo","readTokens","plan","data","status","fromCache","assigneeUid","undefined","constraints","push","dueFrom","dueBefore","tasks","direction","idField","truncated","length","CRM_RECORD_TASK_LIMIT","useCrmRecordTasks","record","field","contactId","companyId","dealId","id"],"mappings":"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"}
@@ -0,0 +1,55 @@
1
+ import type { GridColDef, GridColumnVisibilityModel, GridSortModel } from '@mui/x-data-grid';
2
+ import type { CrmSavedViewController } from './use-crm-saved-view';
3
+ /**
4
+ * The visible columns as the view orders them, and the one way to move one.
5
+ *
6
+ * What the column menu's Move left / Move right read and call — see
7
+ * `crm-column-menu.tsx`. The grid itself cannot reorder a column (the MIT
8
+ * grid forces `disableColumnReorder`), so the order is the view's to keep
9
+ * and the hook's to apply.
10
+ */
11
+ export interface CrmColumnOrder {
12
+ /** The visible, hideable columns by field, first to last as the grid shows them. */
13
+ order: readonly string[];
14
+ /** Swap a column with its visible neighbor: `-1` toward the front, `1` toward the end. */
15
+ move: (field: string, delta: -1 | 1) => void;
16
+ }
17
+ /**
18
+ * The grid's columns, column and sort models, as a saved view holds them
19
+ * (AGL-2617).
20
+ *
21
+ * A view stores the VISIBLE columns by field, in order, and one sort; the
22
+ * grid speaks a column array, a visibility map and a sort array. This is
23
+ * the one translation, so all five lists hand the grid the same controlled
24
+ * models and read the same changes back. An empty column list means the
25
+ * list's own default — every hideable column shown, in the list's order —
26
+ * and a change that arrives back at that default is stored as the empty
27
+ * list rather than as a copy of today's columns, so a view saved before a
28
+ * column existed shows the new column too.
29
+ *
30
+ * ## The order is the view's
31
+ *
32
+ * `columns` is the caller's list re-arranged: the hideable columns take
33
+ * the view's order, and a column the list pins (`hideable: false`, an
34
+ * actions column) keeps the slot it was given. The grid rebuilds its own
35
+ * order from the array whenever it changes, so handing it the arranged
36
+ * array IS the reorder — and a change to the visible set keeps the order
37
+ * the reader had, rather than falling back to the list's.
38
+ *
39
+ * `hidden` is what the list keeps out of sight by default — the
40
+ * filter-only columns the contacts grammar declares, and an optional column
41
+ * a reader turns on when they want it — and is folded into the default
42
+ * model, so the empty list means the columns the list opens with rather than
43
+ * every column it has, and a view that shows an optional column stores it
44
+ * by name.
45
+ */
46
+ export declare function useCrmViewGrid(controller: Pick<CrmSavedViewController, 'state' | 'setColumns' | 'setSort'>, columns: readonly GridColDef[], hidden?: Readonly<Record<string, boolean>>): {
47
+ /** The caller's columns, in the view's order. */
48
+ columns: GridColDef[];
49
+ columnVisibilityModel: GridColumnVisibilityModel;
50
+ onColumnVisibilityModelChange: (model: GridColumnVisibilityModel) => void;
51
+ columnOrder: CrmColumnOrder;
52
+ sortModel: GridSortModel;
53
+ onSortModelChange: (model: GridSortModel) => void;
54
+ };
55
+ export default useCrmViewGrid;
@@ -0,0 +1,170 @@
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 { useCallback, useMemo } from "react";
19
+ /**
20
+ * Every hideable field in the view's order: the ones the view names, as it
21
+ * names them, then the rest in the list's own order.
22
+ *
23
+ * A column the view does not name is a hidden one (or one that did not
24
+ * exist when the view was saved), so its place is invisible until it is
25
+ * shown — and then it joins after the named ones, which is where the
26
+ * Manage columns panel listed it. A name the list no longer has is dropped
27
+ * rather than kept as a phantom slot.
28
+ */ function orderFields(listFields, named) {
29
+ const known = new Set(listFields);
30
+ const placed = named.filter((field)=>known.has(field));
31
+ if (!placed.length) return [
32
+ ...listFields
33
+ ];
34
+ const taken = new Set(placed);
35
+ return [
36
+ ...placed,
37
+ ...listFields.filter((field)=>!taken.has(field))
38
+ ];
39
+ }
40
+ const sameOrder = (a, b)=>a.length === b.length && a.every((field, index)=>field === b[index]);
41
+ /**
42
+ * The grid's columns, column and sort models, as a saved view holds them
43
+ * (AGL-2617).
44
+ *
45
+ * A view stores the VISIBLE columns by field, in order, and one sort; the
46
+ * grid speaks a column array, a visibility map and a sort array. This is
47
+ * the one translation, so all five lists hand the grid the same controlled
48
+ * models and read the same changes back. An empty column list means the
49
+ * list's own default — every hideable column shown, in the list's order —
50
+ * and a change that arrives back at that default is stored as the empty
51
+ * list rather than as a copy of today's columns, so a view saved before a
52
+ * column existed shows the new column too.
53
+ *
54
+ * ## The order is the view's
55
+ *
56
+ * `columns` is the caller's list re-arranged: the hideable columns take
57
+ * the view's order, and a column the list pins (`hideable: false`, an
58
+ * actions column) keeps the slot it was given. The grid rebuilds its own
59
+ * order from the array whenever it changes, so handing it the arranged
60
+ * array IS the reorder — and a change to the visible set keeps the order
61
+ * the reader had, rather than falling back to the list's.
62
+ *
63
+ * `hidden` is what the list keeps out of sight by default — the
64
+ * filter-only columns the contacts grammar declares, and an optional column
65
+ * a reader turns on when they want it — and is folded into the default
66
+ * model, so the empty list means the columns the list opens with rather than
67
+ * every column it has, and a view that shows an optional column stores it
68
+ * by name.
69
+ */ export function useCrmViewGrid(controller, columns, hidden = {}) {
70
+ const { state, setColumns, setSort } = controller;
71
+ const hideable = useMemo(()=>columns.filter((column)=>column.hideable !== false).map((column)=>column.field), [
72
+ columns
73
+ ]);
74
+ /** Every hideable field, in the view's order. */ const ordered = useMemo(()=>orderFields(hideable, state.columns), [
75
+ hideable,
76
+ state.columns
77
+ ]);
78
+ const orderedColumns = useMemo(()=>{
79
+ const byField = new Map(columns.map((column)=>[
80
+ column.field,
81
+ column
82
+ ]));
83
+ let next = 0;
84
+ // A pinned column keeps its slot; each hideable slot is refilled in order.
85
+ return columns.map((column)=>{
86
+ var _byField_get;
87
+ return column.hideable === false ? column : (_byField_get = byField.get(ordered[next++])) != null ? _byField_get : column;
88
+ });
89
+ }, [
90
+ columns,
91
+ ordered
92
+ ]);
93
+ const columnVisibilityModel = useMemo(()=>{
94
+ const model = _extends({}, hidden);
95
+ if (!state.columns.length) return model;
96
+ for (const field of hideable)model[field] = state.columns.includes(field);
97
+ return model;
98
+ }, [
99
+ hidden,
100
+ state.columns,
101
+ hideable
102
+ ]);
103
+ /** The columns the list opens with: every hideable one not hidden by default, in list order. */ const defaultVisible = useMemo(()=>hideable.filter((field)=>hidden[field] !== false), [
104
+ hideable,
105
+ hidden
106
+ ]);
107
+ /** The visible columns in the view's order — what a store writes back. */ const visibleInOrder = useMemo(()=>ordered.filter((field)=>columnVisibilityModel[field] !== false), [
108
+ ordered,
109
+ columnVisibilityModel
110
+ ]);
111
+ const store = useCallback((visible)=>setColumns(sameOrder(visible, defaultVisible) ? [] : visible), [
112
+ setColumns,
113
+ defaultVisible
114
+ ]);
115
+ const onColumnVisibilityModelChange = useCallback((model)=>{
116
+ store(ordered.filter((field)=>model[field] !== false));
117
+ }, [
118
+ ordered,
119
+ store
120
+ ]);
121
+ const move = useCallback((field, delta)=>{
122
+ const from = visibleInOrder.indexOf(field);
123
+ const to = from + delta;
124
+ if (from === -1 || to < 0 || to >= visibleInOrder.length) return;
125
+ const next = [
126
+ ...visibleInOrder
127
+ ];
128
+ next[from] = visibleInOrder[to];
129
+ next[to] = field;
130
+ store(next);
131
+ }, [
132
+ visibleInOrder,
133
+ store
134
+ ]);
135
+ const columnOrder = useMemo(()=>({
136
+ order: visibleInOrder,
137
+ move
138
+ }), [
139
+ visibleInOrder,
140
+ move
141
+ ]);
142
+ const sortModel = useMemo(()=>state.sort ? [
143
+ {
144
+ field: state.sort.field,
145
+ sort: state.sort.direction
146
+ }
147
+ ] : [], [
148
+ state.sort
149
+ ]);
150
+ const onSortModelChange = useCallback((model)=>{
151
+ const first = model[0];
152
+ setSort(first && first.sort ? {
153
+ field: first.field,
154
+ direction: first.sort === 'desc' ? 'desc' : 'asc'
155
+ } : null);
156
+ }, [
157
+ setSort
158
+ ]);
159
+ return {
160
+ columns: orderedColumns,
161
+ columnVisibilityModel,
162
+ onColumnVisibilityModelChange,
163
+ columnOrder,
164
+ sortModel,
165
+ onSortModelChange
166
+ };
167
+ }
168
+ export default useCrmViewGrid;
169
+
170
+ //# sourceMappingURL=use-crm-view-grid.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../../../libs/plugins/crm/src/lib/hooks/use-crm-view-grid.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'use client'\n\nimport type {\n GridColDef,\n GridColumnVisibilityModel,\n GridSortModel,\n} from '@mui/x-data-grid'\nimport { useCallback, useMemo } from 'react'\nimport type { CrmSavedViewController } from './use-crm-saved-view'\n\n/**\n * The visible columns as the view orders them, and the one way to move one.\n *\n * What the column menu's Move left / Move right read and call — see\n * `crm-column-menu.tsx`. The grid itself cannot reorder a column (the MIT\n * grid forces `disableColumnReorder`), so the order is the view's to keep\n * and the hook's to apply.\n */\nexport interface CrmColumnOrder {\n /** The visible, hideable columns by field, first to last as the grid shows them. */\n order: readonly string[]\n /** Swap a column with its visible neighbor: `-1` toward the front, `1` toward the end. */\n move: (field: string, delta: -1 | 1) => void\n}\n\n/**\n * Every hideable field in the view's order: the ones the view names, as it\n * names them, then the rest in the list's own order.\n *\n * A column the view does not name is a hidden one (or one that did not\n * exist when the view was saved), so its place is invisible until it is\n * shown — and then it joins after the named ones, which is where the\n * Manage columns panel listed it. A name the list no longer has is dropped\n * rather than kept as a phantom slot.\n */\nfunction orderFields(listFields: readonly string[], named: readonly string[]): string[] {\n const known = new Set(listFields)\n const placed = named.filter((field) => known.has(field))\n if (!placed.length) return [...listFields]\n const taken = new Set(placed)\n return [...placed, ...listFields.filter((field) => !taken.has(field))]\n}\n\nconst sameOrder = (a: readonly string[], b: readonly string[]): boolean =>\n a.length === b.length && a.every((field, index) => field === b[index])\n\n/**\n * The grid's columns, column and sort models, as a saved view holds them\n * (AGL-2617).\n *\n * A view stores the VISIBLE columns by field, in order, and one sort; the\n * grid speaks a column array, a visibility map and a sort array. This is\n * the one translation, so all five lists hand the grid the same controlled\n * models and read the same changes back. An empty column list means the\n * list's own default — every hideable column shown, in the list's order —\n * and a change that arrives back at that default is stored as the empty\n * list rather than as a copy of today's columns, so a view saved before a\n * column existed shows the new column too.\n *\n * ## The order is the view's\n *\n * `columns` is the caller's list re-arranged: the hideable columns take\n * the view's order, and a column the list pins (`hideable: false`, an\n * actions column) keeps the slot it was given. The grid rebuilds its own\n * order from the array whenever it changes, so handing it the arranged\n * array IS the reorder — and a change to the visible set keeps the order\n * the reader had, rather than falling back to the list's.\n *\n * `hidden` is what the list keeps out of sight by default — the\n * filter-only columns the contacts grammar declares, and an optional column\n * a reader turns on when they want it — and is folded into the default\n * model, so the empty list means the columns the list opens with rather than\n * every column it has, and a view that shows an optional column stores it\n * by name.\n */\nexport function useCrmViewGrid(\n controller: Pick<CrmSavedViewController, 'state' | 'setColumns' | 'setSort'>,\n columns: readonly GridColDef[],\n hidden: Readonly<Record<string, boolean>> = {},\n): {\n /** The caller's columns, in the view's order. */\n columns: GridColDef[]\n columnVisibilityModel: GridColumnVisibilityModel\n onColumnVisibilityModelChange: (model: GridColumnVisibilityModel) => void\n columnOrder: CrmColumnOrder\n sortModel: GridSortModel\n onSortModelChange: (model: GridSortModel) => void\n} {\n const { state, setColumns, setSort } = controller\n const hideable = useMemo(\n () => columns.filter((column) => column.hideable !== false).map((column) => column.field),\n [columns],\n )\n\n /** Every hideable field, in the view's order. */\n const ordered = useMemo(() => orderFields(hideable, state.columns), [hideable, state.columns])\n\n const orderedColumns = useMemo(() => {\n const byField = new Map(columns.map((column) => [column.field, column]))\n let next = 0\n // A pinned column keeps its slot; each hideable slot is refilled in order.\n return columns.map((column) =>\n column.hideable === false ? column : (byField.get(ordered[next++]) ?? column),\n )\n }, [columns, ordered])\n\n const columnVisibilityModel = useMemo<GridColumnVisibilityModel>(() => {\n const model: GridColumnVisibilityModel = { ...hidden }\n if (!state.columns.length) return model\n for (const field of hideable) model[field] = state.columns.includes(field)\n return model\n }, [hidden, state.columns, hideable])\n\n /** The columns the list opens with: every hideable one not hidden by default, in list order. */\n const defaultVisible = useMemo(\n () => hideable.filter((field) => hidden[field] !== false),\n [hideable, hidden],\n )\n\n /** The visible columns in the view's order — what a store writes back. */\n const visibleInOrder = useMemo(\n () => ordered.filter((field) => columnVisibilityModel[field] !== false),\n [ordered, columnVisibilityModel],\n )\n\n const store = useCallback(\n (visible: string[]) => setColumns(sameOrder(visible, defaultVisible) ? [] : visible),\n [setColumns, defaultVisible],\n )\n\n const onColumnVisibilityModelChange = useCallback(\n (model: GridColumnVisibilityModel) => {\n store(ordered.filter((field) => model[field] !== false))\n },\n [ordered, store],\n )\n\n const move = useCallback(\n (field: string, delta: -1 | 1) => {\n const from = visibleInOrder.indexOf(field)\n const to = from + delta\n if (from === -1 || to < 0 || to >= visibleInOrder.length) return\n const next = [...visibleInOrder]\n next[from] = visibleInOrder[to]\n next[to] = field\n store(next)\n },\n [visibleInOrder, store],\n )\n\n const columnOrder = useMemo<CrmColumnOrder>(\n () => ({ order: visibleInOrder, move }),\n [visibleInOrder, move],\n )\n\n const sortModel = useMemo<GridSortModel>(\n () => (state.sort ? [{ field: state.sort.field, sort: state.sort.direction }] : []),\n [state.sort],\n )\n\n const onSortModelChange = useCallback(\n (model: GridSortModel) => {\n const first = model[0]\n setSort(\n first && first.sort\n ? { field: first.field, direction: first.sort === 'desc' ? 'desc' : 'asc' }\n : null,\n )\n },\n [setSort],\n )\n\n return {\n columns: orderedColumns,\n columnVisibilityModel,\n onColumnVisibilityModelChange,\n columnOrder,\n sortModel,\n onSortModelChange,\n }\n}\n\nexport default useCrmViewGrid\n"],"names":["useCallback","useMemo","orderFields","listFields","named","known","Set","placed","filter","field","has","length","taken","sameOrder","a","b","every","index","useCrmViewGrid","controller","columns","hidden","state","setColumns","setSort","hideable","column","map","ordered","orderedColumns","byField","Map","next","get","columnVisibilityModel","model","includes","defaultVisible","visibleInOrder","store","visible","onColumnVisibilityModelChange","move","delta","from","indexOf","to","columnOrder","order","sortModel","sort","direction","onSortModelChange","first"],"mappings":"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"}
@@ -0,0 +1,42 @@
1
+ import { type CrmSavedView, type CrmViewSection } from '@aglyn/aglyn';
2
+ /** One saved view as the menu lists it: the document, held to shape, with its id. */
3
+ export interface CrmSavedViewRow extends CrmSavedView {
4
+ $id: string;
5
+ }
6
+ /**
7
+ * The menu's window.
8
+ *
9
+ * A LOOKUP, not a list: nothing pages this, a reader opens a menu rather
10
+ * than walking it, and a hundred named views for one section of one org is
11
+ * past what anybody scrolls. Bounded so the listen cannot grow with the
12
+ * org; a view past the window is still reachable by its address, which
13
+ * resolves through the same rows and so reads as "not listed" rather than
14
+ * as missing — see the controller.
15
+ */
16
+ export declare const CRM_VIEWS_LIMIT = 100;
17
+ /**
18
+ * The saved views of one section, mine and shared (AGL-2617).
19
+ *
20
+ * ONE listener, filtered on the reader's own tokens like every CRM read,
21
+ * narrowed to the section and ordered by name — the `(visibleTo, section,
22
+ * name)` index. What the rules admit is wider than what the menu shows: a
23
+ * colleague's private view is readable under the contacts predicate and
24
+ * hidden here by `crmViewIsListed`, because the privacy of a working
25
+ * arrangement is a courtesy between colleagues rather than a disclosure
26
+ * boundary, and a rule per reader would need a query per reader.
27
+ *
28
+ * `orderBy('name')` also FILTERS: a view written without a name would be
29
+ * missing from its own menu. The controller refuses an empty name, which is
30
+ * the only writer.
31
+ */
32
+ export declare function useCrmViews(options: {
33
+ scope: readonly ['orgs', string] | null;
34
+ /** The reader's tokens, or `null` at the organization level — no clause (AGL-2630). */
35
+ visibleTo: readonly string[] | null;
36
+ section: CrmViewSection;
37
+ uid: string | null | undefined;
38
+ }): {
39
+ views: CrmSavedViewRow[];
40
+ ready: boolean;
41
+ };
42
+ export default useCrmViews;