@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,329 @@
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 { CRM_COLLECTIONS, CRM_VIEW_NAME_MAX, crmViewStateEquals, EMPTY_CRM_VIEW_STATE, ORG_SCOPE_TOKEN } from "@aglyn/aglyn";
19
+ import { useFirestore, useScopeTokens, useUser } from "@aglyn/tenant-feature-instance";
20
+ import { addDoc, collection, deleteDoc, doc, updateDoc } from "firebase/firestore";
21
+ import { useRouter, useSearchParams } from "next/navigation";
22
+ import { useCallback, useEffect, useMemo, useRef, useState } from "react";
23
+ import { crmRoutes } from "../model/crm-routes.js";
24
+ import { crmViewHref, crmViewIdFromParams } from "../model/crm-view-param.js";
25
+ import { useCrmScope } from "./use-crm-scope.js";
26
+ import { useCrmDefaultView } from "./use-crm-default-view.js";
27
+ import { useCrmViews } from "./use-crm-views.js";
28
+ /**
29
+ * The address value that means "no view, whatever my default is".
30
+ *
31
+ * Without it, choosing the plain list would clear the key and the default
32
+ * would reapply on the next render — the reader could never leave their
33
+ * own default. Written only when a default exists to be overridden, so an
34
+ * address stays clean for a reader who never set one.
35
+ */ export const CRM_VIEW_NONE = 'all';
36
+ /**
37
+ * One section's saved views, resolved against its address (AGL-2617).
38
+ *
39
+ * The controller behind the views control on every CRM list. It owns three
40
+ * things the list used to keep in loose state and lose on reload: which
41
+ * view is open, what the reader has changed since, and how that gets back
42
+ * to the document.
43
+ *
44
+ * ## The address is the truth about which view is open
45
+ *
46
+ * `?view=<id>` names the view; choosing one navigates. So a view is a link,
47
+ * Back returns to the one before it, and a reload lands where the reader
48
+ * was. When the address names nothing, the reader's default for this
49
+ * section (their own profile's) opens instead — unless the list was opened
50
+ * FOR something, a form's captures or one address, in which case the plain
51
+ * list shows what it was asked for and nothing narrows it further.
52
+ *
53
+ * ## The seed is kept, first
54
+ *
55
+ * A Contacts address that carries a seed and a view means both: the seed's
56
+ * clause leads the view's, so the query serves the seed (it reaches the
57
+ * whole collection, as it did before views existed) and the view narrows
58
+ * the window. That is why `initial` folds into every baseline rather than
59
+ * being a starting state the view replaces.
60
+ *
61
+ * ## A view's state is applied once per view
62
+ *
63
+ * When the address names a view, its stored filters, columns and sort
64
+ * become the working state the moment the listing carries it — once. A
65
+ * later change to the document does not overwrite what the reader is in
66
+ * the middle of; a change the reader makes is theirs until they save it or
67
+ * reset. The default applies only onto an untouched plain list, so a reader
68
+ * who started narrowing before their profile arrived keeps what they typed.
69
+ */ export function useCrmSavedView(options) {
70
+ var _ref, _ref1, _ref2, _ref3;
71
+ var _options_initial, _options_initial1, _options_initial2;
72
+ const { section, hostId, org, basePath } = options;
73
+ const initialFilters = (_ref = (_options_initial = options.initial) == null ? void 0 : _options_initial.filters) != null ? _ref : EMPTY_CRM_VIEW_STATE.filters;
74
+ const initialColumns = (_ref1 = (_options_initial1 = options.initial) == null ? void 0 : _options_initial1.columns) != null ? _ref1 : EMPTY_CRM_VIEW_STATE.columns;
75
+ const initialSort = (_ref2 = (_options_initial2 = options.initial) == null ? void 0 : _options_initial2.sort) != null ? _ref2 : EMPTY_CRM_VIEW_STATE.sort;
76
+ const seeded = initialFilters.length > 0;
77
+ const firestore = useFirestore();
78
+ const router = useRouter();
79
+ const searchParams = useSearchParams();
80
+ const { data: user } = useUser();
81
+ const uid = (_ref3 = user == null ? void 0 : user.uid) != null ? _ref3 : null;
82
+ const { scope, orgId, visibleTo, createTokens } = useCrmScope({
83
+ hostId,
84
+ org
85
+ });
86
+ const reach = useScopeTokens(orgId != null ? orgId : undefined);
87
+ const { views, ready } = useCrmViews({
88
+ scope,
89
+ visibleTo,
90
+ section,
91
+ uid
92
+ });
93
+ const { defaultViewId, ready: defaultReady, setDefault: writeDefault } = useCrmDefaultView({
94
+ uid,
95
+ orgId,
96
+ section
97
+ });
98
+ const sectionPath = useMemo(()=>crmRoutes(basePath).section(section), [
99
+ basePath,
100
+ section
101
+ ]);
102
+ /*
103
+ * Which view the address asks for. `all` is the reader stepping out of
104
+ * their default on purpose; nothing at all defers to the default, except
105
+ * on a seeded list, which shows what it was opened for.
106
+ */ const addressed = crmViewIdFromParams(searchParams);
107
+ const currentId = addressed === CRM_VIEW_NONE ? null : addressed != null ? addressed : seeded ? null : defaultViewId;
108
+ const current = useMemo(()=>{
109
+ var _views_find;
110
+ return currentId ? (_views_find = views.find((view)=>view.$id === currentId)) != null ? _views_find : null : null;
111
+ }, [
112
+ views,
113
+ currentId
114
+ ]);
115
+ const missing = Boolean(currentId) && ready && defaultReady && !current;
116
+ /** What the list opens on for a view — the seed in front — or for none. */ const baseline = useCallback((view)=>{
117
+ var _view_sort;
118
+ return view ? {
119
+ filters: [
120
+ ...initialFilters,
121
+ ...view.filters
122
+ ],
123
+ columns: view.columns.length ? view.columns : initialColumns,
124
+ sort: (_view_sort = view.sort) != null ? _view_sort : initialSort
125
+ } : {
126
+ filters: initialFilters,
127
+ columns: initialColumns,
128
+ sort: initialSort
129
+ };
130
+ }, [
131
+ initialFilters,
132
+ initialColumns,
133
+ initialSort
134
+ ]);
135
+ const [state, setState] = useState(()=>baseline(null));
136
+ /** The view whose state the working state was last set from — `''` for none. */ const applied = useRef('');
137
+ const dirty = !crmViewStateEquals(state, baseline(current));
138
+ useEffect(()=>{
139
+ var _ref;
140
+ const target = (_ref = current == null ? void 0 : current.$id) != null ? _ref : '';
141
+ if (applied.current === target) return;
142
+ // A default arriving under a list the reader already narrowed is not
143
+ // allowed to take that narrowing away; an explicit choice always is.
144
+ if (target && !addressed && dirty) return;
145
+ applied.current = target;
146
+ setState(baseline(current));
147
+ }, [
148
+ current,
149
+ addressed,
150
+ dirty,
151
+ baseline
152
+ ]);
153
+ const setFilters = useCallback((filters)=>setState((prev)=>_extends({}, prev, {
154
+ filters
155
+ })), []);
156
+ const setColumns = useCallback((columns)=>setState((prev)=>_extends({}, prev, {
157
+ columns
158
+ })), []);
159
+ const setSort = useCallback((sort)=>setState((prev)=>_extends({}, prev, {
160
+ sort
161
+ })), []);
162
+ const reset = useCallback(()=>setState(baseline(current)), [
163
+ baseline,
164
+ current
165
+ ]);
166
+ const select = useCallback((viewId)=>{
167
+ // Leaving a view for the plain list under a default has to SAY so,
168
+ // or the default would reopen on the next render.
169
+ const value = viewId != null ? viewId : defaultViewId ? CRM_VIEW_NONE : null;
170
+ router.push(crmViewHref(sectionPath, searchParams, value));
171
+ }, [
172
+ router,
173
+ sectionPath,
174
+ searchParams,
175
+ defaultViewId
176
+ ]);
177
+ const [busy, setBusy] = useState(false);
178
+ const guarded = useCallback(async (work)=>{
179
+ setBusy(true);
180
+ try {
181
+ return await work();
182
+ } finally{
183
+ setBusy(false);
184
+ }
185
+ }, []);
186
+ const viewRef = useCallback((viewId)=>scope ? doc(firestore, scope[0], scope[1], CRM_COLLECTIONS.views, viewId) : null, [
187
+ firestore,
188
+ scope
189
+ ]);
190
+ /** The three list-facing fields as the document stores them — without the seed. */ const stored = useCallback(()=>({
191
+ // The seed is the address's, not the view's: a view saved while a
192
+ // form's captures were open must not carry that form forever.
193
+ filters: state.filters.filter((clause)=>!initialFilters.some((seed)=>seed.field === clause.field && seed.op === clause.op && seed.value === clause.value)),
194
+ columns: state.columns,
195
+ sort: state.sort
196
+ }), [
197
+ state,
198
+ initialFilters
199
+ ]);
200
+ const save = useCallback(async ()=>{
201
+ const ref = current ? viewRef(current.$id) : null;
202
+ if (!ref) return;
203
+ await guarded(()=>updateDoc(ref, _extends({}, stored(), {
204
+ updatedAt: new Date()
205
+ })));
206
+ }, [
207
+ current,
208
+ viewRef,
209
+ guarded,
210
+ stored
211
+ ]);
212
+ const saveAs = useCallback(async (name, shared)=>{
213
+ const trimmed = name.trim().slice(0, CRM_VIEW_NAME_MAX);
214
+ if (!trimmed || !scope || !uid) return null;
215
+ const created = await guarded(()=>addDoc(collection(firestore, scope[0], scope[1], CRM_COLLECTIONS.views), _extends({
216
+ section,
217
+ name: trimmed
218
+ }, stored(), {
219
+ ownerUid: uid,
220
+ createdByUid: uid,
221
+ shared,
222
+ // A view made at the organization level belongs to the org
223
+ // (AGL-2630): it names no site, and it is stamped org-wide so
224
+ // every site's reader lists it — unlike a record, a view is a
225
+ // working arrangement, not a person's data.
226
+ hostId: hostId != null ? hostId : null,
227
+ visibleTo: hostId ? createTokens : [
228
+ ORG_SCOPE_TOKEN
229
+ ],
230
+ createdAt: new Date(),
231
+ updatedAt: new Date()
232
+ })));
233
+ // The new view's state IS the working state, so nothing is lost when
234
+ // the address changes and the listing catches up.
235
+ applied.current = created.id;
236
+ select(created.id);
237
+ return created.id;
238
+ }, [
239
+ scope,
240
+ uid,
241
+ guarded,
242
+ firestore,
243
+ section,
244
+ stored,
245
+ hostId,
246
+ createTokens,
247
+ select
248
+ ]);
249
+ const rename = useCallback(async (name)=>{
250
+ const trimmed = name.trim().slice(0, CRM_VIEW_NAME_MAX);
251
+ const ref = current ? viewRef(current.$id) : null;
252
+ if (!trimmed || !ref) return;
253
+ await guarded(()=>updateDoc(ref, {
254
+ name: trimmed,
255
+ updatedAt: new Date()
256
+ }));
257
+ }, [
258
+ current,
259
+ viewRef,
260
+ guarded
261
+ ]);
262
+ const setShared = useCallback(async (shared)=>{
263
+ const ref = current ? viewRef(current.$id) : null;
264
+ if (!ref) return;
265
+ await guarded(()=>updateDoc(ref, {
266
+ shared,
267
+ updatedAt: new Date()
268
+ }));
269
+ }, [
270
+ current,
271
+ viewRef,
272
+ guarded
273
+ ]);
274
+ const isDefault = Boolean(currentId) && defaultViewId === currentId;
275
+ const setDefault = useCallback(async (viewId)=>{
276
+ await guarded(()=>writeDefault(viewId));
277
+ }, [
278
+ guarded,
279
+ writeDefault
280
+ ]);
281
+ const remove = useCallback(async ()=>{
282
+ const ref = current ? viewRef(current.$id) : null;
283
+ if (!ref || !current) return;
284
+ await guarded(async ()=>{
285
+ await deleteDoc(ref);
286
+ // A default pointing at nothing would open every visit on "missing".
287
+ if (defaultViewId === current.$id) await writeDefault(null);
288
+ });
289
+ applied.current = '';
290
+ select(null);
291
+ }, [
292
+ current,
293
+ viewRef,
294
+ guarded,
295
+ defaultViewId,
296
+ writeDefault,
297
+ select
298
+ ]);
299
+ const canEdit = Boolean(current && uid && (current.createdByUid === uid || reach.loaded && reach.orgWide));
300
+ return {
301
+ section,
302
+ views,
303
+ ready: ready && defaultReady,
304
+ current,
305
+ currentId,
306
+ missing,
307
+ state,
308
+ setFilters,
309
+ setColumns,
310
+ setSort,
311
+ dirty,
312
+ canEdit,
313
+ uid,
314
+ select,
315
+ reset,
316
+ save,
317
+ saveAs,
318
+ rename,
319
+ setShared,
320
+ remove,
321
+ defaultViewId,
322
+ isDefault,
323
+ setDefault,
324
+ busy
325
+ };
326
+ }
327
+ export default useCrmSavedView;
328
+
329
+ //# sourceMappingURL=use-crm-saved-view.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../../../libs/plugins/crm/src/lib/hooks/use-crm-saved-view.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 CRM_COLLECTIONS,\n CRM_VIEW_NAME_MAX,\n type CrmViewFilterClause,\n type CrmViewSection,\n type CrmViewSort,\n type CrmViewState,\n crmViewStateEquals,\n EMPTY_CRM_VIEW_STATE,\n ORG_SCOPE_TOKEN,\n} from '@aglyn/aglyn'\nimport {\n useFirestore,\n useScopeTokens,\n useUser,\n} from '@aglyn/tenant-feature-instance'\nimport {\n addDoc,\n collection,\n deleteDoc,\n doc,\n updateDoc,\n} from 'firebase/firestore'\nimport { useRouter, useSearchParams } from 'next/navigation'\nimport { useCallback, useEffect, useMemo, useRef, useState } from 'react'\nimport { crmRoutes } from '../model/crm-routes'\nimport { crmViewHref, crmViewIdFromParams } from '../model/crm-view-param'\nimport { type CrmOrgDoc, useCrmScope } from './use-crm-scope'\nimport { useCrmDefaultView } from './use-crm-default-view'\nimport { type CrmSavedViewRow, useCrmViews } from './use-crm-views'\n\n/**\n * The address value that means \"no view, whatever my default is\".\n *\n * Without it, choosing the plain list would clear the key and the default\n * would reapply on the next render — the reader could never leave their\n * own default. Written only when a default exists to be overridden, so an\n * address stays clean for a reader who never set one.\n */\nexport const CRM_VIEW_NONE = 'all'\n\n/** What a section holds of its saved views, and can do with them. */\nexport interface CrmSavedViewController {\n section: CrmViewSection\n /** Mine and shared, by name. */\n views: CrmSavedViewRow[]\n /** Whether the listing has settled — a missing view is not missing until it has. */\n ready: boolean\n /** The view the list is showing, when the address or the default names a listed one. */\n current: CrmSavedViewRow | null\n /** The id the address names, listed or not. */\n currentId: string | null\n /** The address names a view the listing does not carry. */\n missing: boolean\n /** The list's working state: what the reader has narrowed, shown and sorted. */\n state: CrmViewState\n setFilters: (filters: CrmViewFilterClause[]) => void\n setColumns: (columns: string[]) => void\n setSort: (sort: CrmViewSort | null) => void\n /** The working state differs from the view it started from. */\n dirty: boolean\n /** The reader may change or remove the current view — its creator, or an org-wide member. */\n canEdit: boolean\n uid: string | null\n /** Open a view by id, or the plain list with `null`. */\n select: (viewId: string | null) => void\n /** Back to the view's saved state, or the plain list's. */\n reset: () => void\n save: () => Promise<void>\n /** Creates, opens, and answers with the new id. */\n saveAs: (name: string, shared: boolean) => Promise<string | null>\n rename: (name: string) => Promise<void>\n setShared: (shared: boolean) => Promise<void>\n remove: () => Promise<void>\n defaultViewId: string | null\n isDefault: boolean\n setDefault: (viewId: string | null) => Promise<void>\n /** A write is in flight. */\n busy: boolean\n}\n\n/**\n * One section's saved views, resolved against its address (AGL-2617).\n *\n * The controller behind the views control on every CRM list. It owns three\n * things the list used to keep in loose state and lose on reload: which\n * view is open, what the reader has changed since, and how that gets back\n * to the document.\n *\n * ## The address is the truth about which view is open\n *\n * `?view=<id>` names the view; choosing one navigates. So a view is a link,\n * Back returns to the one before it, and a reload lands where the reader\n * was. When the address names nothing, the reader's default for this\n * section (their own profile's) opens instead — unless the list was opened\n * FOR something, a form's captures or one address, in which case the plain\n * list shows what it was asked for and nothing narrows it further.\n *\n * ## The seed is kept, first\n *\n * A Contacts address that carries a seed and a view means both: the seed's\n * clause leads the view's, so the query serves the seed (it reaches the\n * whole collection, as it did before views existed) and the view narrows\n * the window. That is why `initial` folds into every baseline rather than\n * being a starting state the view replaces.\n *\n * ## A view's state is applied once per view\n *\n * When the address names a view, its stored filters, columns and sort\n * become the working state the moment the listing carries it — once. A\n * later change to the document does not overwrite what the reader is in\n * the middle of; a change the reader makes is theirs until they save it or\n * reset. The default applies only onto an untouched plain list, so a reader\n * who started narrowing before their profile arrived keeps what they typed.\n */\nexport function useCrmSavedView(options: {\n section: CrmViewSection\n /** The site the list is read under, or `null` at the organization level. */\n hostId: string | null\n org?: CrmOrgDoc\n /** The CRM hub path the section hangs beneath — what the address is built from. */\n basePath: string\n /** What the list was opened for: clauses every baseline keeps in front. */\n initial?: Partial<CrmViewState>\n}): CrmSavedViewController {\n const { section, hostId, org, basePath } = options\n const initialFilters = options.initial?.filters ?? EMPTY_CRM_VIEW_STATE.filters\n const initialColumns = options.initial?.columns ?? EMPTY_CRM_VIEW_STATE.columns\n const initialSort = options.initial?.sort ?? EMPTY_CRM_VIEW_STATE.sort\n const seeded = initialFilters.length > 0\n\n const firestore = useFirestore()\n const router = useRouter()\n const searchParams = useSearchParams()\n const { data: user } = useUser()\n const uid = (user as { uid?: string } | null | undefined)?.uid ?? null\n const { scope, orgId, visibleTo, createTokens } = useCrmScope({ hostId, org })\n const reach = useScopeTokens(orgId ?? undefined)\n const { views, ready } = useCrmViews({ scope, visibleTo, section, uid })\n const {\n defaultViewId,\n ready: defaultReady,\n setDefault: writeDefault,\n } = useCrmDefaultView({ uid, orgId, section })\n\n const sectionPath = useMemo(\n () => crmRoutes(basePath).section(section),\n [basePath, section],\n )\n\n /*\n * Which view the address asks for. `all` is the reader stepping out of\n * their default on purpose; nothing at all defers to the default, except\n * on a seeded list, which shows what it was opened for.\n */\n const addressed = crmViewIdFromParams(searchParams)\n const currentId =\n addressed === CRM_VIEW_NONE\n ? null\n : addressed ?? (seeded ? null : defaultViewId)\n const current = useMemo(\n () => (currentId ? views.find((view) => view.$id === currentId) ?? null : null),\n [views, currentId],\n )\n const missing = Boolean(currentId) && ready && defaultReady && !current\n\n /** What the list opens on for a view — the seed in front — or for none. */\n const baseline = useCallback(\n (view: CrmSavedViewRow | null): CrmViewState =>\n view\n ? {\n filters: [...initialFilters, ...view.filters],\n columns: view.columns.length ? view.columns : initialColumns,\n sort: view.sort ?? initialSort,\n }\n : { filters: initialFilters, columns: initialColumns, sort: initialSort },\n [initialFilters, initialColumns, initialSort],\n )\n\n const [state, setState] = useState<CrmViewState>(() => baseline(null))\n /** The view whose state the working state was last set from — `''` for none. */\n const applied = useRef<string>('')\n const dirty = !crmViewStateEquals(state, baseline(current))\n\n useEffect(() => {\n const target = current?.$id ?? ''\n if (applied.current === target) return\n // A default arriving under a list the reader already narrowed is not\n // allowed to take that narrowing away; an explicit choice always is.\n if (target && !addressed && dirty) return\n applied.current = target\n setState(baseline(current))\n }, [current, addressed, dirty, baseline])\n\n const setFilters = useCallback(\n (filters: CrmViewFilterClause[]) => setState((prev) => ({ ...prev, filters })),\n [],\n )\n const setColumns = useCallback(\n (columns: string[]) => setState((prev) => ({ ...prev, columns })),\n [],\n )\n const setSort = useCallback(\n (sort: CrmViewSort | null) => setState((prev) => ({ ...prev, sort })),\n [],\n )\n const reset = useCallback(() => setState(baseline(current)), [baseline, current])\n\n const select = useCallback(\n (viewId: string | null) => {\n // Leaving a view for the plain list under a default has to SAY so,\n // or the default would reopen on the next render.\n const value = viewId ?? (defaultViewId ? CRM_VIEW_NONE : null)\n router.push(crmViewHref(sectionPath, searchParams, value))\n },\n [router, sectionPath, searchParams, defaultViewId],\n )\n\n const [busy, setBusy] = useState(false)\n const guarded = useCallback(async <T,>(work: () => Promise<T>): Promise<T> => {\n setBusy(true)\n try {\n return await work()\n } finally {\n setBusy(false)\n }\n }, [])\n\n const viewRef = useCallback(\n (viewId: string) =>\n scope ? doc(firestore, scope[0], scope[1], CRM_COLLECTIONS.views, viewId) : null,\n [firestore, scope],\n )\n\n /** The three list-facing fields as the document stores them — without the seed. */\n const stored = useCallback(\n (): CrmViewState => ({\n // The seed is the address's, not the view's: a view saved while a\n // form's captures were open must not carry that form forever.\n filters: state.filters.filter(\n (clause) =>\n !initialFilters.some(\n (seed) =>\n seed.field === clause.field &&\n seed.op === clause.op &&\n seed.value === clause.value,\n ),\n ),\n columns: state.columns,\n sort: state.sort,\n }),\n [state, initialFilters],\n )\n\n const save = useCallback(async () => {\n const ref = current ? viewRef(current.$id) : null\n if (!ref) return\n await guarded(() => updateDoc(ref, { ...stored(), updatedAt: new Date() }))\n }, [current, viewRef, guarded, stored])\n\n const saveAs = useCallback(\n async (name: string, shared: boolean) => {\n const trimmed = name.trim().slice(0, CRM_VIEW_NAME_MAX)\n if (!trimmed || !scope || !uid) return null\n const created = await guarded(() =>\n addDoc(collection(firestore, scope[0], scope[1], CRM_COLLECTIONS.views), {\n section,\n name: trimmed,\n ...stored(),\n ownerUid: uid,\n createdByUid: uid,\n shared,\n // A view made at the organization level belongs to the org\n // (AGL-2630): it names no site, and it is stamped org-wide so\n // every site's reader lists it — unlike a record, a view is a\n // working arrangement, not a person's data.\n hostId: hostId ?? null,\n visibleTo: hostId ? createTokens : [ORG_SCOPE_TOKEN],\n createdAt: new Date(),\n updatedAt: new Date(),\n }),\n )\n // The new view's state IS the working state, so nothing is lost when\n // the address changes and the listing catches up.\n applied.current = created.id\n select(created.id)\n return created.id\n },\n [scope, uid, guarded, firestore, section, stored, hostId, createTokens, select],\n )\n\n const rename = useCallback(\n async (name: string) => {\n const trimmed = name.trim().slice(0, CRM_VIEW_NAME_MAX)\n const ref = current ? viewRef(current.$id) : null\n if (!trimmed || !ref) return\n await guarded(() => updateDoc(ref, { name: trimmed, updatedAt: new Date() }))\n },\n [current, viewRef, guarded],\n )\n\n const setShared = useCallback(\n async (shared: boolean) => {\n const ref = current ? viewRef(current.$id) : null\n if (!ref) return\n await guarded(() => updateDoc(ref, { shared, updatedAt: new Date() }))\n },\n [current, viewRef, guarded],\n )\n\n const isDefault = Boolean(currentId) && defaultViewId === currentId\n\n const setDefault = useCallback(\n async (viewId: string | null) => {\n await guarded(() => writeDefault(viewId))\n },\n [guarded, writeDefault],\n )\n\n const remove = useCallback(async () => {\n const ref = current ? viewRef(current.$id) : null\n if (!ref || !current) return\n await guarded(async () => {\n await deleteDoc(ref)\n // A default pointing at nothing would open every visit on \"missing\".\n if (defaultViewId === current.$id) await writeDefault(null)\n })\n applied.current = ''\n select(null)\n }, [current, viewRef, guarded, defaultViewId, writeDefault, select])\n\n const canEdit = Boolean(\n current &&\n uid &&\n (current.createdByUid === uid || (reach.loaded && reach.orgWide)),\n )\n\n return {\n section,\n views,\n ready: ready && defaultReady,\n current,\n currentId,\n missing,\n state,\n setFilters,\n setColumns,\n setSort,\n dirty,\n canEdit,\n uid,\n select,\n reset,\n save,\n saveAs,\n rename,\n setShared,\n remove,\n defaultViewId,\n isDefault,\n setDefault,\n busy,\n }\n}\n\nexport default useCrmSavedView\n"],"names":["CRM_COLLECTIONS","CRM_VIEW_NAME_MAX","crmViewStateEquals","EMPTY_CRM_VIEW_STATE","ORG_SCOPE_TOKEN","useFirestore","useScopeTokens","useUser","addDoc","collection","deleteDoc","doc","updateDoc","useRouter","useSearchParams","useCallback","useEffect","useMemo","useRef","useState","crmRoutes","crmViewHref","crmViewIdFromParams","useCrmScope","useCrmDefaultView","useCrmViews","CRM_VIEW_NONE","useCrmSavedView","options","section","hostId","org","basePath","initialFilters","initial","filters","initialColumns","columns","initialSort","sort","seeded","length","firestore","router","searchParams","data","user","uid","scope","orgId","visibleTo","createTokens","reach","undefined","views","ready","defaultViewId","defaultReady","setDefault","writeDefault","sectionPath","addressed","currentId","current","find","view","$id","missing","Boolean","baseline","state","setState","applied","dirty","target","setFilters","prev","setColumns","setSort","reset","select","viewId","value","push","busy","setBusy","guarded","work","viewRef","stored","filter","clause","some","seed","field","op","save","ref","updatedAt","Date","saveAs","name","shared","trimmed","trim","slice","created","ownerUid","createdByUid","createdAt","id","rename","setShared","isDefault","remove","canEdit","loaded","orgWide"],"mappings":"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"}
@@ -0,0 +1,117 @@
1
+ import { type ConsentGroup, type ConsolePluginPageProps, type ScopeToken } from '@aglyn/aglyn';
2
+ import { type QueryConstraint } from 'firebase/firestore';
3
+ /**
4
+ * The org document as a CRM surface receives it: the shell's typed billing
5
+ * projection on a page, or the plain record a card was handed. Read as a
6
+ * record at the one seam below, so no component casts it itself.
7
+ */
8
+ export type CrmOrgDoc = ConsolePluginPageProps['org'] | Record<string, unknown> | null | undefined;
9
+ /** Where a CRM surface is mounted: under one site, or over the whole org. */
10
+ export type CrmScopeLevel = 'site' | 'org';
11
+ export interface CrmScope {
12
+ /** The org data root, or `null` until the org lookup settles or when there is none. */
13
+ scope: readonly ['orgs', string] | null;
14
+ /** The owning org, or null while the lookup runs or when there is none. */
15
+ orgId: string | null;
16
+ /** Whether the org lookup has settled — `orgId` null after this means no org. */
17
+ ready: boolean;
18
+ /** Under a site, or at the organization level (AGL-2630). */
19
+ level: CrmScopeLevel;
20
+ /** The mounted site, or `null` at the organization level. */
21
+ hostId: string | null;
22
+ /**
23
+ * The controller this surface is being viewed as, or `null` at the org
24
+ * level, where there is no one viewing site: a cross-holder reader
25
+ * resolves each contact's own facet instead (`contactPrimaryGroup`).
26
+ */
27
+ consentGroup: ConsentGroup | null;
28
+ /**
29
+ * What this viewer may LIST — every listener's `array-contains-any`
30
+ * predicate, capped at what the operator accepts — or `null` at the org
31
+ * level, where an org-wide member's listeners carry NO scope clause: the
32
+ * rules' `canReadScoped()` short-circuits on `isOrgWideMember()`, so the
33
+ * clause would only ever narrow what the reader is already allowed. Hand
34
+ * it to {@link crmVisibleToClause}, which spells both cases. Stable across
35
+ * renders for the same org and site, so it can sit in a query's
36
+ * dependency list.
37
+ */
38
+ visibleTo: readonly ScopeToken[] | null;
39
+ /**
40
+ * The site a record this viewer CREATES is captured by: the mounted site,
41
+ * or at the org level the site the reader picked (`null` until they
42
+ * have). A create must hold until this is known — the tokens below are
43
+ * empty without it, and a record stamped with none is visible to nobody.
44
+ */
45
+ createHostId: string | null;
46
+ /** The consent group of {@link createHostId} — what a create records consent for. */
47
+ createGroup: ConsentGroup | null;
48
+ /** What a record this viewer CREATES is stamped with; empty until {@link createHostId} is known. */
49
+ createTokens: readonly ScopeToken[];
50
+ }
51
+ /**
52
+ * The scope facts every CRM surface needs, resolved once (AGL-2597, one
53
+ * hook since AGL-2614, two levels since AGL-2630).
54
+ *
55
+ * A CRM surface — a list, a record page, a drawer, a card on somebody
56
+ * else's page — resolves its consent group, builds the token list its
57
+ * listener filters on, builds the tokens a create stamps, and looks up the
58
+ * org root. Every section needs the same answers, and for a while the deals
59
+ * had a hook of their own that answered them under different names
60
+ * (`readTokens` for `visibleTo`), which is two chances to filter by one set
61
+ * of tokens and stamp with another. This is the one place the expression
62
+ * lives: a surface that spelled its own could omit the `'org'` token and
63
+ * stop listing the org-wide records the rules would have let it read.
64
+ *
65
+ * ## Two levels, one call
66
+ *
67
+ * Under a site, `hostId` names it and everything follows from the org
68
+ * document and that id, as it always has. At the ORGANIZATION level the
69
+ * hub hands every surface `hostId: null`, and the org comes from the mount
70
+ * the hub published (`useCrmOrgMount`): the org root is known at once,
71
+ * reads are unscoped, and the site a create stamps from is the one the
72
+ * reader picked. A surface written against `{ scope, visibleTo,
73
+ * createTokens }` serves both levels without knowing which it is on — the
74
+ * two differences it cannot ignore are that `visibleTo` and `consentGroup`
75
+ * are `null` at the org level, and both are typed to say so.
76
+ *
77
+ * `visibleTo` and `createTokens` are different questions with different
78
+ * answers. The first is the union of everything this viewer may see; the
79
+ * second is where a new record lands, which `crmScopeTokens` decides from
80
+ * the org's default and is narrower — a group of one site creates for that
81
+ * site, and reads the org-wide rows beside its own.
82
+ *
83
+ * Pure over the org document the shell already passed, so it costs no read;
84
+ * only the org lookup behind `useOrgDataScope` is asynchronous, and `ready`
85
+ * is how a surface tells "not yet" from "no org".
86
+ */
87
+ export declare function useCrmScope(props: {
88
+ hostId: string | null | undefined;
89
+ org?: CrmOrgDoc;
90
+ }): CrmScope;
91
+ /**
92
+ * The scope clause a CRM listener carries, spelled once for both levels
93
+ * (AGL-2630).
94
+ *
95
+ * Under a site: `where('visibleTo', 'array-contains-any', tokens)`, the
96
+ * predicate the rules evaluate with `hasAny`, which is what makes a
97
+ * filtered query provable per document. At the org level: NOTHING — the
98
+ * reader is an org-wide member, the rules admit them to every row, and a
99
+ * query that kept the clause would need the org's whole site list on it
100
+ * and still miss a site the list did not carry. Spread into the query, so
101
+ * the two cases are one line at every listener: `...crmVisibleToClause(
102
+ * scope.visibleTo)`.
103
+ *
104
+ * A query that drops an `array-contains-any` may need a composite index
105
+ * the scoped form did not: the equality and range clauses beside it stay,
106
+ * and Firestore composes them on their own. The org-level entries live in
107
+ * `cloud/firebase-firestore.indexes.json` beside their scoped twins.
108
+ */
109
+ export declare function crmVisibleToClause(visibleTo: readonly ScopeToken[] | readonly string[] | null | undefined): QueryConstraint[];
110
+ /**
111
+ * Whether a listener that filters on `visibleTo` has anything to ask for:
112
+ * `true` at the org level (no clause is a complete question), and under a
113
+ * site only when the token list is non-empty — an `array-contains-any`
114
+ * over nothing is a query Firestore refuses.
115
+ */
116
+ export declare function crmScopeListable(visibleTo: readonly ScopeToken[] | readonly string[] | null | undefined): boolean;
117
+ export default useCrmScope;
@@ -0,0 +1,147 @@
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 { consentGroupForHost, crmReadTokens, crmScopeTokens } from "@aglyn/aglyn";
18
+ import { useOrgDataScope } from "@aglyn/tenant-feature-instance";
19
+ import { where } from "firebase/firestore";
20
+ import { useMemo } from "react";
21
+ import { useCrmOrgMount } from "./use-crm-org-mount.js";
22
+ const NO_TOKENS = Object.freeze([]);
23
+ /**
24
+ * The scope facts every CRM surface needs, resolved once (AGL-2597, one
25
+ * hook since AGL-2614, two levels since AGL-2630).
26
+ *
27
+ * A CRM surface — a list, a record page, a drawer, a card on somebody
28
+ * else's page — resolves its consent group, builds the token list its
29
+ * listener filters on, builds the tokens a create stamps, and looks up the
30
+ * org root. Every section needs the same answers, and for a while the deals
31
+ * had a hook of their own that answered them under different names
32
+ * (`readTokens` for `visibleTo`), which is two chances to filter by one set
33
+ * of tokens and stamp with another. This is the one place the expression
34
+ * lives: a surface that spelled its own could omit the `'org'` token and
35
+ * stop listing the org-wide records the rules would have let it read.
36
+ *
37
+ * ## Two levels, one call
38
+ *
39
+ * Under a site, `hostId` names it and everything follows from the org
40
+ * document and that id, as it always has. At the ORGANIZATION level the
41
+ * hub hands every surface `hostId: null`, and the org comes from the mount
42
+ * the hub published (`useCrmOrgMount`): the org root is known at once,
43
+ * reads are unscoped, and the site a create stamps from is the one the
44
+ * reader picked. A surface written against `{ scope, visibleTo,
45
+ * createTokens }` serves both levels without knowing which it is on — the
46
+ * two differences it cannot ignore are that `visibleTo` and `consentGroup`
47
+ * are `null` at the org level, and both are typed to say so.
48
+ *
49
+ * `visibleTo` and `createTokens` are different questions with different
50
+ * answers. The first is the union of everything this viewer may see; the
51
+ * second is where a new record lands, which `crmScopeTokens` decides from
52
+ * the org's default and is narrower — a group of one site creates for that
53
+ * site, and reads the org-wide rows beside its own.
54
+ *
55
+ * Pure over the org document the shell already passed, so it costs no read;
56
+ * only the org lookup behind `useOrgDataScope` is asynchronous, and `ready`
57
+ * is how a surface tells "not yet" from "no org".
58
+ */ export function useCrmScope(props) {
59
+ var _props_org, _ref;
60
+ const hostId = props.hostId || null;
61
+ const org = (_props_org = props.org) != null ? _props_org : null;
62
+ const mount = useCrmOrgMount();
63
+ // Under a site the org is looked up from the host index; at the org level
64
+ // it is the mount's, known at once. A `null` host with no mount is a
65
+ // surface mounted nowhere, and resolves to no org rather than guessing.
66
+ const { scope, orgId, ready } = useOrgDataScope(hostId ? {
67
+ hostId
68
+ } : {
69
+ orgId: mount == null ? void 0 : mount.orgId
70
+ });
71
+ const level = hostId ? 'site' : 'org';
72
+ const consentGroup = useMemo(()=>hostId ? consentGroupForHost(org, hostId) : null, [
73
+ org,
74
+ hostId
75
+ ]);
76
+ const visibleTo = useMemo(()=>consentGroup ? crmReadTokens(consentGroup) : null, [
77
+ consentGroup
78
+ ]);
79
+ const createHostId = (_ref = hostId != null ? hostId : mount == null ? void 0 : mount.createHostId) != null ? _ref : null;
80
+ const createGroup = useMemo(()=>createHostId ? consentGroupForHost(org, createHostId) : null, [
81
+ org,
82
+ createHostId
83
+ ]);
84
+ const createTokens = useMemo(()=>createGroup ? crmScopeTokens(org, createGroup) : NO_TOKENS, [
85
+ org,
86
+ createGroup
87
+ ]);
88
+ return useMemo(()=>({
89
+ scope,
90
+ orgId,
91
+ ready,
92
+ level,
93
+ hostId,
94
+ consentGroup,
95
+ visibleTo,
96
+ createHostId,
97
+ createGroup,
98
+ createTokens
99
+ }), [
100
+ scope,
101
+ orgId,
102
+ ready,
103
+ level,
104
+ hostId,
105
+ consentGroup,
106
+ visibleTo,
107
+ createHostId,
108
+ createGroup,
109
+ createTokens
110
+ ]);
111
+ }
112
+ /**
113
+ * The scope clause a CRM listener carries, spelled once for both levels
114
+ * (AGL-2630).
115
+ *
116
+ * Under a site: `where('visibleTo', 'array-contains-any', tokens)`, the
117
+ * predicate the rules evaluate with `hasAny`, which is what makes a
118
+ * filtered query provable per document. At the org level: NOTHING — the
119
+ * reader is an org-wide member, the rules admit them to every row, and a
120
+ * query that kept the clause would need the org's whole site list on it
121
+ * and still miss a site the list did not carry. Spread into the query, so
122
+ * the two cases are one line at every listener: `...crmVisibleToClause(
123
+ * scope.visibleTo)`.
124
+ *
125
+ * A query that drops an `array-contains-any` may need a composite index
126
+ * the scoped form did not: the equality and range clauses beside it stay,
127
+ * and Firestore composes them on their own. The org-level entries live in
128
+ * `cloud/firebase-firestore.indexes.json` beside their scoped twins.
129
+ */ export function crmVisibleToClause(visibleTo) {
130
+ if (!visibleTo) return [];
131
+ return [
132
+ where('visibleTo', 'array-contains-any', [
133
+ ...visibleTo
134
+ ])
135
+ ];
136
+ }
137
+ /**
138
+ * Whether a listener that filters on `visibleTo` has anything to ask for:
139
+ * `true` at the org level (no clause is a complete question), and under a
140
+ * site only when the token list is non-empty — an `array-contains-any`
141
+ * over nothing is a query Firestore refuses.
142
+ */ export function crmScopeListable(visibleTo) {
143
+ return visibleTo === null || visibleTo === undefined || visibleTo.length > 0;
144
+ }
145
+ export default useCrmScope;
146
+
147
+ //# sourceMappingURL=use-crm-scope.js.map