@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,405 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Aglyn LLC
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */ 'use client';
17
+ import { _ as _extends } from "@swc/helpers/_/_extends";
18
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
19
+ import { contactDisplayName, contactMergePreview, nameSearchKey, normalizeContactEmail } from "@aglyn/aglyn";
20
+ import { useSnackbar } from "@aglyn/shared-ui-snackstack";
21
+ import { useFirestore } from "@aglyn/tenant-feature-instance";
22
+ import { ScrollTable } from "@aglyn/shared-ui-jsx/components/scroll-table.component";
23
+ import { Alert, Button, Dialog, DialogActions, DialogContent, DialogTitle, FormControl, FormControlLabel, FormLabel, List, ListItemButton, ListItemText, Radio, RadioGroup, Stack, TableBody, TableCell, TableHead, TableRow, TextField, Typography } from "@mui/material";
24
+ import { collection, endAt, getDocs, limit, orderBy, query, startAt, where } from "firebase/firestore";
25
+ import { useCallback, useEffect, useMemo, useState } from "react";
26
+ import { useCrmOrgMount } from "../hooks/use-crm-org-mount.js";
27
+ import { crmVisibleToClause } from "../hooks/use-crm-scope.js";
28
+ import { useCrmApi } from "./use-crm-api.js";
29
+ /** How many rows a search answers — a picker, not a list. */ const SEARCH_LIMIT = 8;
30
+ /** The high code point that closes a `nameLower` prefix range. */ const HIGH = '';
31
+ /**
32
+ * The dialog's open state, held by the page so two openers — the record's
33
+ * overflow menu and the likely-duplicates card — share one dialog.
34
+ *
35
+ * The menu opens it empty, to be searched, with the OTHER record surviving:
36
+ * "merge this into…" is what a reader means when they are on the record
37
+ * they want gone. The duplicates card opens it with the candidate already
38
+ * picked and THIS record surviving: the reader is on the record they keep,
39
+ * looking at the copies. Either way the dialog lets them switch.
40
+ */ export function useContactMergeDialog() {
41
+ const [state, setState] = useState({
42
+ open: false,
43
+ other: null,
44
+ keep: 'other'
45
+ });
46
+ const open = useCallback((options = {})=>{
47
+ var _options_other, _options_keep;
48
+ return setState({
49
+ open: true,
50
+ other: (_options_other = options.other) != null ? _options_other : null,
51
+ keep: (_options_keep = options.keep) != null ? _options_keep : options.other ? 'current' : 'other'
52
+ });
53
+ }, []);
54
+ const close = useCallback(()=>setState((previous)=>_extends({}, previous, {
55
+ open: false
56
+ })), []);
57
+ return {
58
+ state,
59
+ open,
60
+ close
61
+ };
62
+ }
63
+ const label = (pick, groupId)=>{
64
+ var _pick_doc_email;
65
+ return contactDisplayName(pick.doc, groupId) || String((_pick_doc_email = pick.doc['email']) != null ? _pick_doc_email : pick.id);
66
+ };
67
+ /**
68
+ * MERGE TWO RECORDS FOR ONE PERSON (AGL-2625).
69
+ *
70
+ * Two steps in one dialog. First the OTHER record, found by address or by
71
+ * name among the contacts this viewer may list — the same two searches the
72
+ * company's contacts card runs, one read each, on ask. Then the two records
73
+ * side by side, field by field, with the value the surviving record will
74
+ * carry and where it came from — `contactMergePreview` is the same rule the
75
+ * server writes with, so what the reader is shown is what lands.
76
+ *
77
+ * The reader picks which record survives. The survivor keeps its address;
78
+ * the other record's address becomes an alternate on it, its deals, tasks,
79
+ * activities and leads move, and the document is deleted. The act is one
80
+ * server route, because it is one transaction over two documents and a
81
+ * repoint of rows a browser may not be able to list.
82
+ */ export function ContactMergeDialog(props) {
83
+ var _current_doc_email, _other_doc_email;
84
+ const { open, onClose, hostId, current, scope, consentGroup, visibleTo, memberName, onMerged } = props;
85
+ const firestore = useFirestore();
86
+ const callCrm = useCrmApi(hostId);
87
+ const { enqueueSnackbar } = useSnackbar();
88
+ const groupId = consentGroup.groupId;
89
+ const orgMount = useCrmOrgMount();
90
+ // A site to run as, or the org to run as (AGL-2634): one of the two is
91
+ // what the route authorizes against, and with neither there is no door.
92
+ const canMerge = Boolean(hostId) || Boolean(orgMount);
93
+ const [other, setOther] = useState(props.other);
94
+ const [keep, setKeep] = useState(props.keep);
95
+ const [term, setTerm] = useState('');
96
+ const [searching, setSearching] = useState(false);
97
+ const [results, setResults] = useState(null);
98
+ const [busy, setBusy] = useState(false);
99
+ const [error, setError] = useState(null);
100
+ // Reset on every open to what the opener handed over.
101
+ useEffect(()=>{
102
+ if (!open) return;
103
+ setOther(props.other);
104
+ setKeep(props.keep);
105
+ setTerm('');
106
+ setResults(null);
107
+ setError(null);
108
+ setBusy(false);
109
+ }, [
110
+ open,
111
+ props.other,
112
+ props.keep
113
+ ]);
114
+ const search = useCallback(async ()=>{
115
+ const raw = term.trim();
116
+ if (!raw || searching) return;
117
+ setSearching(true);
118
+ setError(null);
119
+ try {
120
+ const contactsRef = collection(firestore, scope[0], scope[1], 'contacts');
121
+ const scoped = crmVisibleToClause(visibleTo);
122
+ let found;
123
+ if (raw.includes('@')) {
124
+ const email = normalizeContactEmail(raw);
125
+ if (!email) {
126
+ setResults([]);
127
+ return;
128
+ }
129
+ found = await getDocs(query(contactsRef, ...scoped, where('email', '==', email), limit(SEARCH_LIMIT)));
130
+ } else {
131
+ const key = nameSearchKey(raw);
132
+ found = await getDocs(query(contactsRef, ...scoped, orderBy('nameLower'), startAt(key), endAt(`${key}${HIGH}`), limit(SEARCH_LIMIT)));
133
+ }
134
+ setResults(found.docs.filter((snapshot)=>snapshot.id !== current.id).map((snapshot)=>({
135
+ id: snapshot.id,
136
+ doc: snapshot.data()
137
+ })));
138
+ } catch (searchError) {
139
+ console.error(searchError);
140
+ setResults(null);
141
+ setError('The search could not be run.');
142
+ } finally{
143
+ setSearching(false);
144
+ }
145
+ }, [
146
+ term,
147
+ searching,
148
+ firestore,
149
+ scope,
150
+ visibleTo,
151
+ current.id
152
+ ]);
153
+ const survivor = keep === 'current' ? current : other;
154
+ const merged = keep === 'current' ? other : current;
155
+ const rows = useMemo(()=>survivor && merged ? contactMergePreview(survivor.doc, merged.doc, groupId, {
156
+ memberName
157
+ }) : [], [
158
+ survivor,
159
+ merged,
160
+ groupId,
161
+ memberName
162
+ ]);
163
+ const submit = useCallback(async ()=>{
164
+ if (!survivor || !merged || busy || !canMerge) return;
165
+ setBusy(true);
166
+ setError(null);
167
+ try {
168
+ const { response, payload } = await callCrm('contacts-merge', {
169
+ survivorId: survivor.id,
170
+ mergedId: merged.id
171
+ });
172
+ if (!response.ok) {
173
+ var _payload_error;
174
+ setError(String((_payload_error = payload['error']) != null ? _payload_error : 'The contacts could not be merged.'));
175
+ return;
176
+ }
177
+ enqueueSnackbar('Contacts merged', {
178
+ variant: 'success',
179
+ persist: false
180
+ });
181
+ onClose();
182
+ onMerged == null ? void 0 : onMerged(survivor.id);
183
+ } catch (submitError) {
184
+ console.error(submitError);
185
+ setError('The contacts could not be merged.');
186
+ } finally{
187
+ setBusy(false);
188
+ }
189
+ }, [
190
+ survivor,
191
+ merged,
192
+ busy,
193
+ canMerge,
194
+ callCrm,
195
+ enqueueSnackbar,
196
+ onClose,
197
+ onMerged
198
+ ]);
199
+ const currentLabel = label(current, groupId);
200
+ const otherLabel = other ? label(other, groupId) : '';
201
+ return /*#__PURE__*/ _jsxs(Dialog, {
202
+ open: open,
203
+ onClose: busy ? undefined : onClose,
204
+ maxWidth: "md",
205
+ fullWidth: true,
206
+ children: [
207
+ /*#__PURE__*/ _jsx(DialogTitle, {
208
+ children: 'Merge contacts'
209
+ }),
210
+ /*#__PURE__*/ _jsx(DialogContent, {
211
+ children: /*#__PURE__*/ _jsxs(Stack, {
212
+ spacing: 2,
213
+ sx: {
214
+ pt: 1
215
+ },
216
+ children: [
217
+ !other ? /*#__PURE__*/ _jsxs(_Fragment, {
218
+ children: [
219
+ /*#__PURE__*/ _jsx(Typography, {
220
+ variant: "body2",
221
+ color: "text.secondary",
222
+ children: `Find the other record for ${currentLabel} — by email address, or by name.`
223
+ }),
224
+ /*#__PURE__*/ _jsxs(Stack, {
225
+ direction: "row",
226
+ spacing: 1,
227
+ sx: {
228
+ alignItems: 'flex-start'
229
+ },
230
+ children: [
231
+ /*#__PURE__*/ _jsx(TextField, {
232
+ label: "Email or name",
233
+ value: term,
234
+ onChange: (event)=>setTerm(event.target.value),
235
+ onKeyDown: (event)=>{
236
+ if (event.key === 'Enter') {
237
+ event.preventDefault();
238
+ void search();
239
+ }
240
+ },
241
+ size: "small",
242
+ fullWidth: true,
243
+ autoFocus: true
244
+ }),
245
+ /*#__PURE__*/ _jsx(Button, {
246
+ variant: "outlined",
247
+ onClick: ()=>void search(),
248
+ disabled: !term.trim() || searching,
249
+ children: searching ? 'Searching…' : 'Search'
250
+ })
251
+ ]
252
+ }),
253
+ results ? results.length ? /*#__PURE__*/ _jsx(List, {
254
+ dense: true,
255
+ disablePadding: true,
256
+ "aria-label": "Matching contacts",
257
+ children: results.map((pick)=>{
258
+ var _pick_doc_email;
259
+ return /*#__PURE__*/ _jsx(ListItemButton, {
260
+ onClick: ()=>setOther(pick),
261
+ children: /*#__PURE__*/ _jsx(ListItemText, {
262
+ primary: label(pick, groupId),
263
+ secondary: String((_pick_doc_email = pick.doc['email']) != null ? _pick_doc_email : '')
264
+ })
265
+ }, pick.id);
266
+ })
267
+ }) : /*#__PURE__*/ _jsx(Typography, {
268
+ variant: "body2",
269
+ color: "text.secondary",
270
+ children: 'No other contact matches among the ones you can see.'
271
+ }) : null
272
+ ]
273
+ }) : /*#__PURE__*/ _jsxs(_Fragment, {
274
+ children: [
275
+ /*#__PURE__*/ _jsxs(FormControl, {
276
+ children: [
277
+ /*#__PURE__*/ _jsx(FormLabel, {
278
+ id: "contact-merge-keep",
279
+ children: 'Keep'
280
+ }),
281
+ /*#__PURE__*/ _jsxs(RadioGroup, {
282
+ "aria-labelledby": "contact-merge-keep",
283
+ value: keep,
284
+ onChange: (event)=>setKeep(event.target.value),
285
+ children: [
286
+ /*#__PURE__*/ _jsx(FormControlLabel, {
287
+ value: "current",
288
+ control: /*#__PURE__*/ _jsx(Radio, {
289
+ size: "small"
290
+ }),
291
+ label: `${currentLabel} (${String((_current_doc_email = current.doc['email']) != null ? _current_doc_email : '')})`
292
+ }),
293
+ /*#__PURE__*/ _jsx(FormControlLabel, {
294
+ value: "other",
295
+ control: /*#__PURE__*/ _jsx(Radio, {
296
+ size: "small"
297
+ }),
298
+ label: `${otherLabel} (${String((_other_doc_email = other.doc['email']) != null ? _other_doc_email : '')})`
299
+ })
300
+ ]
301
+ })
302
+ ]
303
+ }),
304
+ /*#__PURE__*/ _jsx(Typography, {
305
+ variant: "body2",
306
+ color: "text.secondary",
307
+ children: 'The kept record keeps every value it has; empty fields fill from the ' + 'other record. Tags, filings and the timeline are combined, and the ' + "other record's deals, tasks, activities and leads move across. Its " + 'address becomes an alternate on the kept record, so a later capture ' + 'on it lands here — and the other record is deleted.'
308
+ }),
309
+ /*#__PURE__*/ _jsxs(ScrollTable, {
310
+ size: "small",
311
+ "aria-label": "What the merge keeps",
312
+ children: [
313
+ /*#__PURE__*/ _jsx(TableHead, {
314
+ children: /*#__PURE__*/ _jsxs(TableRow, {
315
+ children: [
316
+ /*#__PURE__*/ _jsx(TableCell, {
317
+ children: 'Field'
318
+ }),
319
+ /*#__PURE__*/ _jsx(TableCell, {
320
+ children: 'Kept'
321
+ }),
322
+ /*#__PURE__*/ _jsx(TableCell, {
323
+ children: 'Merged'
324
+ }),
325
+ /*#__PURE__*/ _jsx(TableCell, {
326
+ children: 'After'
327
+ })
328
+ ]
329
+ })
330
+ }),
331
+ /*#__PURE__*/ _jsx(TableBody, {
332
+ children: rows.map((row)=>/*#__PURE__*/ _jsxs(TableRow, {
333
+ children: [
334
+ /*#__PURE__*/ _jsx(TableCell, {
335
+ component: "th",
336
+ scope: "row",
337
+ children: row.label
338
+ }),
339
+ /*#__PURE__*/ _jsx(TableCell, {
340
+ sx: {
341
+ whiteSpace: 'pre-wrap'
342
+ },
343
+ children: row.survivor
344
+ }),
345
+ /*#__PURE__*/ _jsx(TableCell, {
346
+ sx: {
347
+ whiteSpace: 'pre-wrap'
348
+ },
349
+ children: row.merged
350
+ }),
351
+ /*#__PURE__*/ _jsx(TableCell, {
352
+ sx: {
353
+ whiteSpace: 'pre-wrap',
354
+ fontWeight: row.from === 'merged' || row.from === 'both' ? 600 : undefined
355
+ },
356
+ children: row.result
357
+ })
358
+ ]
359
+ }, row.key))
360
+ })
361
+ ]
362
+ }),
363
+ !props.other ? /*#__PURE__*/ _jsx(Button, {
364
+ size: "small",
365
+ onClick: ()=>setOther(null),
366
+ sx: {
367
+ alignSelf: 'flex-start'
368
+ },
369
+ children: 'Pick a different contact'
370
+ }) : null
371
+ ]
372
+ }),
373
+ error ? /*#__PURE__*/ _jsx(Alert, {
374
+ severity: "error",
375
+ children: error
376
+ }) : null,
377
+ !canMerge ? /*#__PURE__*/ _jsx(Alert, {
378
+ severity: "info",
379
+ children: 'No site has captured this contact, so there is no site to ' + 'merge it from. Open it from one of your sites instead.'
380
+ }) : null
381
+ ]
382
+ })
383
+ }),
384
+ /*#__PURE__*/ _jsxs(DialogActions, {
385
+ children: [
386
+ /*#__PURE__*/ _jsx(Button, {
387
+ onClick: onClose,
388
+ disabled: busy,
389
+ children: 'Cancel'
390
+ }),
391
+ /*#__PURE__*/ _jsx(Button, {
392
+ variant: "contained",
393
+ onClick: ()=>void submit(),
394
+ disabled: !other || busy || !canMerge,
395
+ children: busy ? 'Merging…' : 'Merge'
396
+ })
397
+ ]
398
+ })
399
+ ]
400
+ });
401
+ }
402
+ ContactMergeDialog.displayName = 'ContactMergeDialog';
403
+ export default ContactMergeDialog;
404
+
405
+ //# sourceMappingURL=contact-merge-dialog.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../../../libs/plugins/crm/src/lib/components/contact-merge-dialog.tsx"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n'use client'\n\nimport {\n type ConsentGroup,\n type ContactMergePreviewRow,\n contactDisplayName,\n contactMergePreview,\n nameSearchKey,\n normalizeContactEmail,\n} from '@aglyn/aglyn'\nimport { useSnackbar } from '@aglyn/shared-ui-snackstack'\nimport { useFirestore } from '@aglyn/tenant-feature-instance'\nimport { ScrollTable } from '@aglyn/shared-ui-jsx/components/scroll-table.component'\nimport {\n Alert,\n Button,\n Dialog,\n DialogActions,\n DialogContent,\n DialogTitle,\n FormControl,\n FormControlLabel,\n FormLabel,\n List,\n ListItemButton,\n ListItemText,\n Radio,\n RadioGroup,\n Stack,\n TableBody,\n TableCell,\n TableHead,\n TableRow,\n TextField,\n Typography,\n} from '@mui/material'\nimport {\n collection,\n endAt,\n getDocs,\n limit,\n orderBy,\n query,\n startAt,\n where,\n} from 'firebase/firestore'\nimport { useCallback, useEffect, useMemo, useState } from 'react'\nimport { useCrmOrgMount } from '../hooks/use-crm-org-mount'\nimport { crmVisibleToClause } from '../hooks/use-crm-scope'\nimport { useCrmApi } from './use-crm-api'\n\n/** One contact as the dialog holds it: its id and the document as read. */\nexport interface ContactPick {\n id: string\n doc: Record<string, unknown>\n}\n\n/** Which of the two records stays. */\nexport type ContactMergeKeep = 'current' | 'other'\n\n/** How many rows a search answers — a picker, not a list. */\nconst SEARCH_LIMIT = 8\n/** The high code point that closes a `nameLower` prefix range. */\nconst HIGH = ''\n\nexport interface ContactMergeDialogState {\n open: boolean\n /** The record to merge with, when the opener already knows it. */\n other: ContactPick | null\n keep: ContactMergeKeep\n}\n\n/**\n * The dialog's open state, held by the page so two openers — the record's\n * overflow menu and the likely-duplicates card — share one dialog.\n *\n * The menu opens it empty, to be searched, with the OTHER record surviving:\n * \"merge this into…\" is what a reader means when they are on the record\n * they want gone. The duplicates card opens it with the candidate already\n * picked and THIS record surviving: the reader is on the record they keep,\n * looking at the copies. Either way the dialog lets them switch.\n */\nexport function useContactMergeDialog() {\n const [state, setState] = useState<ContactMergeDialogState>({\n open: false,\n other: null,\n keep: 'other',\n })\n const open = useCallback(\n (options: { other?: ContactPick; keep?: ContactMergeKeep } = {}) =>\n setState({\n open: true,\n other: options.other ?? null,\n keep: options.keep ?? (options.other ? 'current' : 'other'),\n }),\n [],\n )\n const close = useCallback(\n () => setState((previous) => ({ ...previous, open: false })),\n [],\n )\n return { state, open, close }\n}\n\nexport interface ContactMergeDialogProps extends ContactMergeDialogState {\n onClose: () => void\n /**\n * The site the merge runs as — the route logs it on that site's feed. At\n * the organization level the record's own capturing site (AGL-2630), or\n * `null` for a row no site has captured: beneath the org hub's mount the\n * route's org variant merges it anyway (AGL-2634), and only a surface\n * mounted nowhere holds the button.\n */\n hostId: string | null\n /** The record whose page this is. */\n current: ContactPick\n /** `['orgs', orgId]` — where the contacts live. */\n scope: readonly [string, string]\n consentGroup: ConsentGroup\n /**\n * What this viewer may list — the search's `array-contains-any` — or\n * `null` at the organization level, where the search carries no clause\n * (AGL-2630).\n */\n visibleTo: readonly string[] | null\n /** The owner's name for a uid, for the preview. */\n memberName?: (uid: string) => string\n /** Told which record survived, once the server has merged. */\n onMerged?: (survivorId: string) => void\n}\n\nconst label = (pick: ContactPick, groupId: string) =>\n contactDisplayName(pick.doc, groupId) || String(pick.doc['email'] ?? pick.id)\n\n/**\n * MERGE TWO RECORDS FOR ONE PERSON (AGL-2625).\n *\n * Two steps in one dialog. First the OTHER record, found by address or by\n * name among the contacts this viewer may list — the same two searches the\n * company's contacts card runs, one read each, on ask. Then the two records\n * side by side, field by field, with the value the surviving record will\n * carry and where it came from — `contactMergePreview` is the same rule the\n * server writes with, so what the reader is shown is what lands.\n *\n * The reader picks which record survives. The survivor keeps its address;\n * the other record's address becomes an alternate on it, its deals, tasks,\n * activities and leads move, and the document is deleted. The act is one\n * server route, because it is one transaction over two documents and a\n * repoint of rows a browser may not be able to list.\n */\nexport function ContactMergeDialog(props: ContactMergeDialogProps) {\n const {\n open,\n onClose,\n hostId,\n current,\n scope,\n consentGroup,\n visibleTo,\n memberName,\n onMerged,\n } = props\n const firestore = useFirestore()\n const callCrm = useCrmApi(hostId)\n const { enqueueSnackbar } = useSnackbar()\n const groupId = consentGroup.groupId\n const orgMount = useCrmOrgMount()\n // A site to run as, or the org to run as (AGL-2634): one of the two is\n // what the route authorizes against, and with neither there is no door.\n const canMerge = Boolean(hostId) || Boolean(orgMount)\n\n const [other, setOther] = useState<ContactPick | null>(props.other)\n const [keep, setKeep] = useState<ContactMergeKeep>(props.keep)\n const [term, setTerm] = useState('')\n const [searching, setSearching] = useState(false)\n const [results, setResults] = useState<ContactPick[] | null>(null)\n const [busy, setBusy] = useState(false)\n const [error, setError] = useState<string | null>(null)\n\n // Reset on every open to what the opener handed over.\n useEffect(() => {\n if (!open) return\n setOther(props.other)\n setKeep(props.keep)\n setTerm('')\n setResults(null)\n setError(null)\n setBusy(false)\n }, [open, props.other, props.keep])\n\n const search = useCallback(async () => {\n const raw = term.trim()\n if (!raw || searching) return\n setSearching(true)\n setError(null)\n try {\n const contactsRef = collection(firestore, scope[0], scope[1], 'contacts')\n const scoped = crmVisibleToClause(visibleTo)\n let found\n if (raw.includes('@')) {\n const email = normalizeContactEmail(raw)\n if (!email) {\n setResults([])\n return\n }\n found = await getDocs(\n query(contactsRef, ...scoped, where('email', '==', email), limit(SEARCH_LIMIT)),\n )\n } else {\n const key = nameSearchKey(raw)\n found = await getDocs(\n query(\n contactsRef,\n ...scoped,\n orderBy('nameLower'),\n startAt(key),\n endAt(`${key}${HIGH}`),\n limit(SEARCH_LIMIT),\n ),\n )\n }\n setResults(\n found.docs\n .filter((snapshot) => snapshot.id !== current.id)\n .map((snapshot) => ({ id: snapshot.id, doc: snapshot.data() })),\n )\n } catch (searchError) {\n console.error(searchError)\n setResults(null)\n setError('The search could not be run.')\n } finally {\n setSearching(false)\n }\n }, [term, searching, firestore, scope, visibleTo, current.id])\n\n const survivor = keep === 'current' ? current : other\n const merged = keep === 'current' ? other : current\n const rows: ContactMergePreviewRow[] = useMemo(\n () =>\n survivor && merged\n ? contactMergePreview(survivor.doc, merged.doc, groupId, { memberName })\n : [],\n [survivor, merged, groupId, memberName],\n )\n\n const submit = useCallback(async () => {\n if (!survivor || !merged || busy || !canMerge) return\n setBusy(true)\n setError(null)\n try {\n const { response, payload } = await callCrm('contacts-merge', {\n survivorId: survivor.id,\n mergedId: merged.id,\n })\n if (!response.ok) {\n setError(String(payload['error'] ?? 'The contacts could not be merged.'))\n return\n }\n enqueueSnackbar('Contacts merged', { variant: 'success', persist: false })\n onClose()\n onMerged?.(survivor.id)\n } catch (submitError) {\n console.error(submitError)\n setError('The contacts could not be merged.')\n } finally {\n setBusy(false)\n }\n }, [survivor, merged, busy, canMerge, callCrm, enqueueSnackbar, onClose, onMerged])\n\n const currentLabel = label(current, groupId)\n const otherLabel = other ? label(other, groupId) : ''\n\n return (\n <Dialog open={open} onClose={busy ? undefined : onClose} maxWidth=\"md\" fullWidth>\n <DialogTitle>{'Merge contacts'}</DialogTitle>\n <DialogContent>\n <Stack spacing={2} sx={{ pt: 1 }}>\n {!other ? (\n <>\n <Typography variant=\"body2\" color=\"text.secondary\">\n {`Find the other record for ${currentLabel} — by email address, or by name.`}\n </Typography>\n <Stack direction=\"row\" spacing={1} sx={{ alignItems: 'flex-start' }}>\n <TextField\n label=\"Email or name\"\n value={term}\n onChange={(event) => setTerm(event.target.value)}\n onKeyDown={(event) => {\n if (event.key === 'Enter') {\n event.preventDefault()\n void search()\n }\n }}\n size=\"small\"\n fullWidth\n autoFocus\n />\n <Button\n variant=\"outlined\"\n onClick={() => void search()}\n disabled={!term.trim() || searching}\n >\n {searching ? 'Searching…' : 'Search'}\n </Button>\n </Stack>\n {results ? (\n results.length ? (\n <List dense disablePadding aria-label=\"Matching contacts\">\n {results.map((pick) => (\n <ListItemButton key={pick.id} onClick={() => setOther(pick)}>\n <ListItemText\n primary={label(pick, groupId)}\n secondary={String(pick.doc['email'] ?? '')}\n />\n </ListItemButton>\n ))}\n </List>\n ) : (\n <Typography variant=\"body2\" color=\"text.secondary\">\n {'No other contact matches among the ones you can see.'}\n </Typography>\n )\n ) : null}\n </>\n ) : (\n <>\n <FormControl>\n <FormLabel id=\"contact-merge-keep\">{'Keep'}</FormLabel>\n <RadioGroup\n aria-labelledby=\"contact-merge-keep\"\n value={keep}\n onChange={(event) => setKeep(event.target.value as ContactMergeKeep)}\n >\n <FormControlLabel\n value=\"current\"\n control={<Radio size=\"small\" />}\n label={`${currentLabel} (${String(current.doc['email'] ?? '')})`}\n />\n <FormControlLabel\n value=\"other\"\n control={<Radio size=\"small\" />}\n label={`${otherLabel} (${String(other.doc['email'] ?? '')})`}\n />\n </RadioGroup>\n </FormControl>\n <Typography variant=\"body2\" color=\"text.secondary\">\n {'The kept record keeps every value it has; empty fields fill from the ' +\n 'other record. Tags, filings and the timeline are combined, and the ' +\n \"other record's deals, tasks, activities and leads move across. Its \" +\n 'address becomes an alternate on the kept record, so a later capture ' +\n 'on it lands here — and the other record is deleted.'}\n </Typography>\n <ScrollTable size=\"small\" aria-label=\"What the merge keeps\">\n <TableHead>\n <TableRow>\n <TableCell>{'Field'}</TableCell>\n <TableCell>{'Kept'}</TableCell>\n <TableCell>{'Merged'}</TableCell>\n <TableCell>{'After'}</TableCell>\n </TableRow>\n </TableHead>\n <TableBody>\n {rows.map((row) => (\n <TableRow key={row.key}>\n <TableCell component=\"th\" scope=\"row\">\n {row.label}\n </TableCell>\n <TableCell sx={{ whiteSpace: 'pre-wrap' }}>{row.survivor}</TableCell>\n <TableCell sx={{ whiteSpace: 'pre-wrap' }}>{row.merged}</TableCell>\n <TableCell\n sx={{\n whiteSpace: 'pre-wrap',\n fontWeight: row.from === 'merged' || row.from === 'both' ? 600 : undefined,\n }}\n >\n {row.result}\n </TableCell>\n </TableRow>\n ))}\n </TableBody>\n </ScrollTable>\n {!props.other ? (\n <Button size=\"small\" onClick={() => setOther(null)} sx={{ alignSelf: 'flex-start' }}>\n {'Pick a different contact'}\n </Button>\n ) : null}\n </>\n )}\n {error ? <Alert severity=\"error\">{error}</Alert> : null}\n {!canMerge ? (\n <Alert severity=\"info\">\n {'No site has captured this contact, so there is no site to ' +\n 'merge it from. Open it from one of your sites instead.'}\n </Alert>\n ) : null}\n </Stack>\n </DialogContent>\n <DialogActions>\n <Button onClick={onClose} disabled={busy}>\n {'Cancel'}\n </Button>\n <Button\n variant=\"contained\"\n onClick={() => void submit()}\n disabled={!other || busy || !canMerge}\n >\n {busy ? 'Merging…' : 'Merge'}\n </Button>\n </DialogActions>\n </Dialog>\n )\n}\nContactMergeDialog.displayName = 'ContactMergeDialog'\n\nexport default ContactMergeDialog\n"],"names":["contactDisplayName","contactMergePreview","nameSearchKey","normalizeContactEmail","useSnackbar","useFirestore","ScrollTable","Alert","Button","Dialog","DialogActions","DialogContent","DialogTitle","FormControl","FormControlLabel","FormLabel","List","ListItemButton","ListItemText","Radio","RadioGroup","Stack","TableBody","TableCell","TableHead","TableRow","TextField","Typography","collection","endAt","getDocs","limit","orderBy","query","startAt","where","useCallback","useEffect","useMemo","useState","useCrmOrgMount","crmVisibleToClause","useCrmApi","SEARCH_LIMIT","HIGH","useContactMergeDialog","state","setState","open","other","keep","options","close","previous","label","pick","groupId","doc","String","id","ContactMergeDialog","props","current","onClose","hostId","scope","consentGroup","visibleTo","memberName","onMerged","firestore","callCrm","enqueueSnackbar","orgMount","canMerge","Boolean","setOther","setKeep","term","setTerm","searching","setSearching","results","setResults","busy","setBusy","error","setError","search","raw","trim","contactsRef","scoped","found","includes","email","key","docs","filter","snapshot","map","data","searchError","console","survivor","merged","rows","submit","response","payload","survivorId","mergedId","ok","variant","persist","submitError","currentLabel","otherLabel","undefined","maxWidth","fullWidth","spacing","sx","pt","color","direction","alignItems","value","onChange","event","target","onKeyDown","preventDefault","size","autoFocus","onClick","disabled","length","dense","disablePadding","aria-label","primary","secondary","aria-labelledby","control","row","component","whiteSpace","fontWeight","from","result","alignSelf","severity","displayName"],"mappings":"AAAA;;;;;;;;;;;;;;;CAeC,GACD;;;AAEA,SAGEA,kBAAkB,EAClBC,mBAAmB,EACnBC,aAAa,EACbC,qBAAqB,QAChB,eAAc;AACrB,SAASC,WAAW,QAAQ,8BAA6B;AACzD,SAASC,YAAY,QAAQ,iCAAgC;AAC7D,SAASC,WAAW,QAAQ,yDAAwD;AACpF,SACEC,KAAK,EACLC,MAAM,EACNC,MAAM,EACNC,aAAa,EACbC,aAAa,EACbC,WAAW,EACXC,WAAW,EACXC,gBAAgB,EAChBC,SAAS,EACTC,IAAI,EACJC,cAAc,EACdC,YAAY,EACZC,KAAK,EACLC,UAAU,EACVC,KAAK,EACLC,SAAS,EACTC,SAAS,EACTC,SAAS,EACTC,QAAQ,EACRC,SAAS,EACTC,UAAU,QACL,gBAAe;AACtB,SACEC,UAAU,EACVC,KAAK,EACLC,OAAO,EACPC,KAAK,EACLC,OAAO,EACPC,KAAK,EACLC,OAAO,EACPC,KAAK,QACA,qBAAoB;AAC3B,SAASC,WAAW,EAAEC,SAAS,EAAEC,OAAO,EAAEC,QAAQ,QAAQ,QAAO;AACjE,SAASC,cAAc,QAAQ,gCAA4B;AAC3D,SAASC,kBAAkB,QAAQ,4BAAwB;AAC3D,SAASC,SAAS,QAAQ,mBAAe;AAWzC,2DAA2D,GAC3D,MAAMC,eAAe;AACrB,gEAAgE,GAChE,MAAMC,OAAO;AASb;;;;;;;;;CASC,GACD,OAAO,SAASC;IACd,MAAM,CAACC,OAAOC,SAAS,GAAGR,SAAkC;QAC1DS,MAAM;QACNC,OAAO;QACPC,MAAM;IACR;IACA,MAAMF,OAAOZ,YACX,CAACe,UAA4D,CAAC,CAAC;YAGpDA,gBACDA;eAHRJ,SAAS;YACPC,MAAM;YACNC,KAAK,GAAEE,iBAAAA,QAAQF,KAAK,YAAbE,iBAAiB;YACxBD,IAAI,GAAEC,gBAAAA,QAAQD,IAAI,YAAZC,gBAAiBA,QAAQF,KAAK,GAAG,YAAY;QACrD;OACF,EAAE;IAEJ,MAAMG,QAAQhB,YACZ,IAAMW,SAAS,CAACM,WAAc,aAAKA;gBAAUL,MAAM;iBACnD,EAAE;IAEJ,OAAO;QAAEF;QAAOE;QAAMI;IAAM;AAC9B;AA6BA,MAAME,QAAQ,CAACC,MAAmBC;QACgBD;WAAhDvD,mBAAmBuD,KAAKE,GAAG,EAAED,YAAYE,QAAOH,kBAAAA,KAAKE,GAAG,CAAC,QAAQ,YAAjBF,kBAAqBA,KAAKI,EAAE;;AAE9E;;;;;;;;;;;;;;;CAeC,GACD,OAAO,SAASC,mBAAmBC,KAA8B;QA0LXC,oBAKFb;IA9LlD,MAAM,EACJD,IAAI,EACJe,OAAO,EACPC,MAAM,EACNF,OAAO,EACPG,KAAK,EACLC,YAAY,EACZC,SAAS,EACTC,UAAU,EACVC,QAAQ,EACT,GAAGR;IACJ,MAAMS,YAAYjE;IAClB,MAAMkE,UAAU7B,UAAUsB;IAC1B,MAAM,EAAEQ,eAAe,EAAE,GAAGpE;IAC5B,MAAMoD,UAAUU,aAAaV,OAAO;IACpC,MAAMiB,WAAWjC;IACjB,uEAAuE;IACvE,wEAAwE;IACxE,MAAMkC,WAAWC,QAAQX,WAAWW,QAAQF;IAE5C,MAAM,CAACxB,OAAO2B,SAAS,GAAGrC,SAA6BsB,MAAMZ,KAAK;IAClE,MAAM,CAACC,MAAM2B,QAAQ,GAAGtC,SAA2BsB,MAAMX,IAAI;IAC7D,MAAM,CAAC4B,MAAMC,QAAQ,GAAGxC,SAAS;IACjC,MAAM,CAACyC,WAAWC,aAAa,GAAG1C,SAAS;IAC3C,MAAM,CAAC2C,SAASC,WAAW,GAAG5C,SAA+B;IAC7D,MAAM,CAAC6C,MAAMC,QAAQ,GAAG9C,SAAS;IACjC,MAAM,CAAC+C,OAAOC,SAAS,GAAGhD,SAAwB;IAElD,sDAAsD;IACtDF,UAAU;QACR,IAAI,CAACW,MAAM;QACX4B,SAASf,MAAMZ,KAAK;QACpB4B,QAAQhB,MAAMX,IAAI;QAClB6B,QAAQ;QACRI,WAAW;QACXI,SAAS;QACTF,QAAQ;IACV,GAAG;QAACrC;QAAMa,MAAMZ,KAAK;QAAEY,MAAMX,IAAI;KAAC;IAElC,MAAMsC,SAASpD,YAAY;QACzB,MAAMqD,MAAMX,KAAKY,IAAI;QACrB,IAAI,CAACD,OAAOT,WAAW;QACvBC,aAAa;QACbM,SAAS;QACT,IAAI;YACF,MAAMI,cAAc/D,WAAW0C,WAAWL,KAAK,CAAC,EAAE,EAAEA,KAAK,CAAC,EAAE,EAAE;YAC9D,MAAM2B,SAASnD,mBAAmB0B;YAClC,IAAI0B;YACJ,IAAIJ,IAAIK,QAAQ,CAAC,MAAM;gBACrB,MAAMC,QAAQ5F,sBAAsBsF;gBACpC,IAAI,CAACM,OAAO;oBACVZ,WAAW,EAAE;oBACb;gBACF;gBACAU,QAAQ,MAAM/D,QACZG,MAAM0D,gBAAgBC,QAAQzD,MAAM,SAAS,MAAM4D,QAAQhE,MAAMY;YAErE,OAAO;gBACL,MAAMqD,MAAM9F,cAAcuF;gBAC1BI,QAAQ,MAAM/D,QACZG,MACE0D,gBACGC,QACH5D,QAAQ,cACRE,QAAQ8D,MACRnE,MAAM,GAAGmE,MAAMpD,MAAM,GACrBb,MAAMY;YAGZ;YACAwC,WACEU,MAAMI,IAAI,CACPC,MAAM,CAAC,CAACC,WAAaA,SAASxC,EAAE,KAAKG,QAAQH,EAAE,EAC/CyC,GAAG,CAAC,CAACD,WAAc,CAAA;oBAAExC,IAAIwC,SAASxC,EAAE;oBAAEF,KAAK0C,SAASE,IAAI;gBAAG,CAAA;QAElE,EAAE,OAAOC,aAAa;YACpBC,QAAQjB,KAAK,CAACgB;YACdnB,WAAW;YACXI,SAAS;QACX,SAAU;YACRN,aAAa;QACf;IACF,GAAG;QAACH;QAAME;QAAWV;QAAWL;QAAOE;QAAWL,QAAQH,EAAE;KAAC;IAE7D,MAAM6C,WAAWtD,SAAS,YAAYY,UAAUb;IAChD,MAAMwD,SAASvD,SAAS,YAAYD,QAAQa;IAC5C,MAAM4C,OAAiCpE,QACrC,IACEkE,YAAYC,SACRxG,oBAAoBuG,SAAS/C,GAAG,EAAEgD,OAAOhD,GAAG,EAAED,SAAS;YAAEY;QAAW,KACpE,EAAE,EACR;QAACoC;QAAUC;QAAQjD;QAASY;KAAW;IAGzC,MAAMuC,SAASvE,YAAY;QACzB,IAAI,CAACoE,YAAY,CAACC,UAAUrB,QAAQ,CAACV,UAAU;QAC/CW,QAAQ;QACRE,SAAS;QACT,IAAI;YACF,MAAM,EAAEqB,QAAQ,EAAEC,OAAO,EAAE,GAAG,MAAMtC,QAAQ,kBAAkB;gBAC5DuC,YAAYN,SAAS7C,EAAE;gBACvBoD,UAAUN,OAAO9C,EAAE;YACrB;YACA,IAAI,CAACiD,SAASI,EAAE,EAAE;oBACAH;gBAAhBtB,SAAS7B,QAAOmD,iBAAAA,OAAO,CAAC,QAAQ,YAAhBA,iBAAoB;gBACpC;YACF;YACArC,gBAAgB,mBAAmB;gBAAEyC,SAAS;gBAAWC,SAAS;YAAM;YACxEnD;YACAM,4BAAAA,SAAWmC,SAAS7C,EAAE;QACxB,EAAE,OAAOwD,aAAa;YACpBZ,QAAQjB,KAAK,CAAC6B;YACd5B,SAAS;QACX,SAAU;YACRF,QAAQ;QACV;IACF,GAAG;QAACmB;QAAUC;QAAQrB;QAAMV;QAAUH;QAASC;QAAiBT;QAASM;KAAS;IAElF,MAAM+C,eAAe9D,MAAMQ,SAASN;IACpC,MAAM6D,aAAapE,QAAQK,MAAML,OAAOO,WAAW;IAEnD,qBACE,MAAC/C;QAAOuC,MAAMA;QAAMe,SAASqB,OAAOkC,YAAYvD;QAASwD,UAAS;QAAKC,SAAS;;0BAC9E,KAAC5G;0BAAa;;0BACd,KAACD;0BACC,cAAA,MAACU;oBAAMoG,SAAS;oBAAGC,IAAI;wBAAEC,IAAI;oBAAE;;wBAC5B,CAAC1E,sBACA;;8CACE,KAACtB;oCAAWsF,SAAQ;oCAAQW,OAAM;8CAC/B,CAAC,0BAA0B,EAAER,aAAa,gCAAgC,CAAC;;8CAE9E,MAAC/F;oCAAMwG,WAAU;oCAAMJ,SAAS;oCAAGC,IAAI;wCAAEI,YAAY;oCAAa;;sDAChE,KAACpG;4CACC4B,OAAM;4CACNyE,OAAOjD;4CACPkD,UAAU,CAACC,QAAUlD,QAAQkD,MAAMC,MAAM,CAACH,KAAK;4CAC/CI,WAAW,CAACF;gDACV,IAAIA,MAAMjC,GAAG,KAAK,SAAS;oDACzBiC,MAAMG,cAAc;oDACpB,KAAK5C;gDACP;4CACF;4CACA6C,MAAK;4CACLb,SAAS;4CACTc,SAAS;;sDAEX,KAAC9H;4CACCyG,SAAQ;4CACRsB,SAAS,IAAM,KAAK/C;4CACpBgD,UAAU,CAAC1D,KAAKY,IAAI,MAAMV;sDAEzBA,YAAY,eAAe;;;;gCAG/BE,UACCA,QAAQuD,MAAM,iBACZ,KAACzH;oCAAK0H,KAAK;oCAACC,cAAc;oCAACC,cAAW;8CACnC1D,QAAQkB,GAAG,CAAC,CAAC7C;4CAIUA;6DAHtB,KAACtC;4CAA6BsH,SAAS,IAAM3D,SAASrB;sDACpD,cAAA,KAACrC;gDACC2H,SAASvF,MAAMC,MAAMC;gDACrBsF,WAAWpF,QAAOH,kBAAAA,KAAKE,GAAG,CAAC,QAAQ,YAAjBF,kBAAqB;;2CAHtBA,KAAKI,EAAE;;mDAShC,KAAChC;oCAAWsF,SAAQ;oCAAQW,OAAM;8CAC/B;qCAGH;;2CAGN;;8CACE,MAAC/G;;sDACC,KAACE;4CAAU4C,IAAG;sDAAsB;;sDACpC,MAACvC;4CACC2H,mBAAgB;4CAChBhB,OAAO7E;4CACP8E,UAAU,CAACC,QAAUpD,QAAQoD,MAAMC,MAAM,CAACH,KAAK;;8DAE/C,KAACjH;oDACCiH,OAAM;oDACNiB,uBAAS,KAAC7H;wDAAMkH,MAAK;;oDACrB/E,OAAO,GAAG8D,aAAa,EAAE,EAAE1D,QAAOI,qBAAAA,QAAQL,GAAG,CAAC,QAAQ,YAApBK,qBAAwB,IAAI,CAAC,CAAC;;8DAElE,KAAChD;oDACCiH,OAAM;oDACNiB,uBAAS,KAAC7H;wDAAMkH,MAAK;;oDACrB/E,OAAO,GAAG+D,WAAW,EAAE,EAAE3D,QAAOT,mBAAAA,MAAMQ,GAAG,CAAC,QAAQ,YAAlBR,mBAAsB,IAAI,CAAC,CAAC;;;;;;8CAIlE,KAACtB;oCAAWsF,SAAQ;oCAAQW,OAAM;8CAC/B,0EACC,wEACA,wEACA,yEACA;;8CAEJ,MAACtH;oCAAY+H,MAAK;oCAAQO,cAAW;;sDACnC,KAACpH;sDACC,cAAA,MAACC;;kEACC,KAACF;kEAAW;;kEACZ,KAACA;kEAAW;;kEACZ,KAACA;kEAAW;;kEACZ,KAACA;kEAAW;;;;;sDAGhB,KAACD;sDACEoF,KAAKN,GAAG,CAAC,CAAC6C,oBACT,MAACxH;;sEACC,KAACF;4DAAU2H,WAAU;4DAAKjF,OAAM;sEAC7BgF,IAAI3F,KAAK;;sEAEZ,KAAC/B;4DAAUmG,IAAI;gEAAEyB,YAAY;4DAAW;sEAAIF,IAAIzC,QAAQ;;sEACxD,KAACjF;4DAAUmG,IAAI;gEAAEyB,YAAY;4DAAW;sEAAIF,IAAIxC,MAAM;;sEACtD,KAAClF;4DACCmG,IAAI;gEACFyB,YAAY;gEACZC,YAAYH,IAAII,IAAI,KAAK,YAAYJ,IAAII,IAAI,KAAK,SAAS,MAAM/B;4DACnE;sEAEC2B,IAAIK,MAAM;;;mDAZAL,IAAIjD,GAAG;;;;gCAkB3B,CAACnC,MAAMZ,KAAK,iBACX,KAACzC;oCAAO6H,MAAK;oCAAQE,SAAS,IAAM3D,SAAS;oCAAO8C,IAAI;wCAAE6B,WAAW;oCAAa;8CAC/E;qCAED;;;wBAGPjE,sBAAQ,KAAC/E;4BAAMiJ,UAAS;sCAASlE;6BAAiB;wBAClD,CAACZ,yBACA,KAACnE;4BAAMiJ,UAAS;sCACb,+DACC;6BAEF;;;;0BAGR,MAAC9I;;kCACC,KAACF;wBAAO+H,SAASxE;wBAASyE,UAAUpD;kCACjC;;kCAEH,KAAC5E;wBACCyG,SAAQ;wBACRsB,SAAS,IAAM,KAAK5B;wBACpB6B,UAAU,CAACvF,SAASmC,QAAQ,CAACV;kCAE5BU,OAAO,aAAa;;;;;;AAK/B;AACAxB,mBAAmB6F,WAAW,GAAG;AAEjC,eAAe7F,mBAAkB"}
@@ -0,0 +1,89 @@
1
+ import { type AglynOrgBilling, type ConsentGroup } from '@aglyn/aglyn';
2
+ import { type ContactRecord } from '../model/contact-record';
3
+ import type { OrgMembers } from './use-org-members';
4
+ export interface ContactPropertiesCardProps {
5
+ /** The site the record is read under, or `null` at the organization level. */
6
+ hostId: string | null;
7
+ /** The org document the shell passed, for the company picker's scope. */
8
+ org?: Partial<AglynOrgBilling> | null;
9
+ /** The row, flattened through the viewing group's facet. */
10
+ record: ContactRecord;
11
+ /** The controller whose facet the edits are saved into. */
12
+ consentGroup: ConsentGroup;
13
+ /**
14
+ * The listener's verdict on the row the drafts were seeded from, for the
15
+ * guard that refuses a save over an unconfirmed read.
16
+ */
17
+ seed: {
18
+ status: 'loading' | 'success' | 'error';
19
+ fromCache: boolean;
20
+ };
21
+ /** The team, for the owner picker and the owner's name. */
22
+ members: OrgMembers;
23
+ /**
24
+ * The org's plan lacks the CRM (AGL-2788), which the shell mounts no CRM
25
+ * page for (AGL-2851). The owner, the lifecycle stage and the company
26
+ * show, locked, and are left out of a save; `crm/contact-update` refuses
27
+ * such a plan the rest of the profile, the tags and the notes too.
28
+ */
29
+ suiteLocked?: boolean;
30
+ }
31
+ /**
32
+ * THE RECORD ITSELF: every field a team keeps on a person, in one card with
33
+ * one Save (AGL-2596).
34
+ *
35
+ * ## One save, one request, one guard
36
+ *
37
+ * A field-at-a-time save would be nine requests and nine chances for the
38
+ * stale-seed guard to refuse one of them — so the card holds a draft of the
39
+ * whole profile and sends it once. The guard WRAPS the send: a row seeded
40
+ * from the cache or from a failed read is refused with the message the guard
41
+ * chooses, and what was typed stays in the fields, because a refusal that
42
+ * also emptied the form would read as a save that worked.
43
+ *
44
+ * ## The server writes the facet (AGL-2804)
45
+ *
46
+ * Every field here lives in THIS holder's facet, and the Firestore rules
47
+ * cannot tell one field of a facet from another, so the card writes nothing
48
+ * itself. The draft goes to `crm/contact-update`, which writes each field by
49
+ * dotted path into the holder's facet — never a nested object, which would
50
+ * take every other holder's records with it — clears a blank field rather
51
+ * than storing it empty, keeps the phone's and the company's search echoes
52
+ * at the top of the document, and refuses every field to a plan without
53
+ * the CRM. A refusal is shown in the route's own words.
54
+ *
55
+ * ## The stage goes to its own route
56
+ *
57
+ * The lifecycle stage is the one field an automation listens for:
58
+ * `contactStageChanged` (AGL-2605) is emitted by `crm/contact-stage` after it
59
+ * performs the write, and by nothing else. So when the stage the reader
60
+ * picked differs from the one the record holds, it is sent to that route
61
+ * once the rest of the profile has landed — the stage picked, or `null` for
62
+ * "Not placed yet", which clears it and announces nothing. A refusal from
63
+ * that route is reported on its own, with its sentence, after the fields that
64
+ * did save.
65
+ *
66
+ * ## The name is an override
67
+ *
68
+ * The canonical name is shared by every site holding the person, so this
69
+ * card never edits it. What it saves is this holder's own name for them,
70
+ * and the helper says what a blank falls back to, so nobody clears the
71
+ * field expecting the record to go nameless.
72
+ *
73
+ * ## Company is a record, with its name kept beside it
74
+ *
75
+ * The Company field is the picker (AGL-2613): the link is `companyId` in
76
+ * this holder's facet, mirrored into the top-level `companyIds` for the
77
+ * company page's query, and the company's contacts count moves with it —
78
+ * all planned by the route from the stored document, so this card never
79
+ * reasons about another holder's link. The name is sent too, from the picked
80
+ * company, because the list column and the global search read the name and
81
+ * not the id; a record that carries a name with no link — an import, a save
82
+ * from before the picker — keeps it as the label, and the picker offers it
83
+ * as the company to link or create.
84
+ */
85
+ export declare function ContactPropertiesCard(props: ContactPropertiesCardProps): import("react").JSX.Element;
86
+ export declare namespace ContactPropertiesCard {
87
+ var displayName: string;
88
+ }
89
+ export default ContactPropertiesCard;