@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,241 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Aglyn LLC
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+ /**
18
+ * The pipeline's arithmetic and the stage editor's rules (AGL-2598), as pure
19
+ * functions — no Firestore, no React — so the board, the table, the detail
20
+ * page and the server route read one definition of "what is this pipeline
21
+ * worth" and "which stage edits are legal".
22
+ */
23
+ import { type CrmDeal, type CrmDealStage, type CrmPipeline } from '@aglyn/aglyn/app-utils/crm';
24
+ /** A deal as the console reads it: the model plus its document id. */
25
+ export type DealDoc = CrmDeal & {
26
+ $id: string;
27
+ /**
28
+ * The contact's and the company's names, copied onto the deal when the
29
+ * link is made. A board of two hundred cards cannot afford a keyed read per
30
+ * card to caption each one, and the caption is allowed to lag a rename —
31
+ * the link itself is the id, which never changes.
32
+ */
33
+ contactName?: string;
34
+ companyName?: string;
35
+ };
36
+ /** A pipeline as the console reads it. */
37
+ export type PipelineDoc = CrmPipeline & {
38
+ $id: string;
39
+ };
40
+ /** The document id the seeded default pipeline is written under. */
41
+ export declare const DEFAULT_PIPELINE_ID = "default";
42
+ /** Name of the pipeline every org starts with. */
43
+ export declare const DEFAULT_PIPELINE_NAME = "Sales";
44
+ export declare const PIPELINE_NAME_MAX = 60;
45
+ /** The pipelines a picker offers and a new deal may land in: the ones not archived. */
46
+ export declare function activePipelines<T extends Pick<CrmPipeline, 'archivedAt'>>(pipelines: readonly T[]): T[];
47
+ /**
48
+ * The pipeline a new deal lands in when nobody picks one: the active one
49
+ * marked default, else the first active one, else nothing. An archived
50
+ * pipeline is never the default even if its flag was left on — archiving
51
+ * clears the flag, but a document written by an older console may not
52
+ * have had it cleared, and a default nobody can create a deal in is a
53
+ * board that opens on a pipeline the picker does not list.
54
+ */
55
+ export declare function defaultPipelineOf<T extends Pick<CrmPipeline, 'archivedAt' | 'isDefault'>>(pipelines: readonly T[]): T | null;
56
+ /**
57
+ * Why a pipeline cannot be created or renamed to `name`, or `null`.
58
+ *
59
+ * Names are unique among the ACTIVE pipelines, compared without case: the
60
+ * picker lists them by name alone, and two rows reading "Sales" would be a
61
+ * choice nobody can make. An archived pipeline's name is free to reuse —
62
+ * "Sales 2025" retired and "Sales" started over is the point of archiving.
63
+ */
64
+ export declare function pipelineNameProblem(name: string, pipelines: ReadonlyArray<Pick<CrmPipeline, 'name' | 'archivedAt'> & {
65
+ $id: string;
66
+ }>, ownId?: string): string | null;
67
+ /**
68
+ * Why a pipeline cannot be archived, or `null` when it can.
69
+ *
70
+ * `openDeals` is the server's count, asked for before this is called, the
71
+ * way `stageRemovalRefusal` asks: an open deal in an archived pipeline is
72
+ * a card on no board, and the count is taken at the click because a deal
73
+ * can be created into the pipeline from another tab meanwhile. The default
74
+ * pipeline cannot go while it is the default — a new deal has to land
75
+ * somewhere — and the last active one cannot go at all, for the same
76
+ * reason from the other side.
77
+ */
78
+ export declare function pipelineArchiveRefusal(pipeline: Pick<CrmPipeline, 'archivedAt' | 'isDefault'> & {
79
+ $id: string;
80
+ }, pipelines: ReadonlyArray<Pick<CrmPipeline, 'archivedAt'> & {
81
+ $id: string;
82
+ }>, openDeals: number): string | null;
83
+ /** What every pipeline write stamps besides its name. */
84
+ export interface PipelineWriteContext {
85
+ visibleTo: readonly string[];
86
+ hostId: string;
87
+ uid: string;
88
+ nowMs: number;
89
+ }
90
+ /**
91
+ * The document a new pipeline is created as: the name, a COPY of the
92
+ * default stages, not the default, active. A copy for the reason
93
+ * `DEFAULT_DEAL_STAGES` gives — a second pipeline seeded later must start
94
+ * from the original set, whatever the first one's editor did to its own.
95
+ */
96
+ export declare function newPipelineDocument(name: string, context: PipelineWriteContext): Record<string, unknown>;
97
+ /**
98
+ * Currencies the amount picker offers, lowercase ISO 4217 as the model
99
+ * stores them. Short on purpose: a picker of a hundred and eighty currencies
100
+ * is a scroll, and a deal in one outside this list is entered through the
101
+ * API with whatever code it carries — the display below formats any code
102
+ * `Intl` knows.
103
+ */
104
+ export declare const DEAL_CURRENCIES: readonly ["usd", "eur", "gbp", "cad", "aud", "nzd", "chf", "jpy", "sek", "nok", "dkk", "mxn", "brl", "inr", "sgd"];
105
+ export declare const DEFAULT_DEAL_CURRENCY = "usd";
106
+ /** How a deal's `status` reads on screen. */
107
+ export declare const DEAL_STATUS_LABELS: Record<CrmDeal['status'], string>;
108
+ /** Cents → the reader's locale, or a plain number when the code is unknown. */
109
+ export declare function formatMoney(cents: number, currency: string | undefined): string;
110
+ /**
111
+ * A typed amount, as cents, or `null` when it is not a number.
112
+ *
113
+ * Accepts what people paste from an invoice — a thousands separator, a
114
+ * currency symbol, surrounding space — and refuses a negative: a deal is
115
+ * worth zero or more, and a negative amount here is a typo rather than a
116
+ * refund. Rounded rather than truncated so `19.995` does not lose a cent.
117
+ */
118
+ export declare function parseAmountInput(input: string): number | null;
119
+ /** Cents → the string the amount field shows, `''` for nothing. */
120
+ export declare function amountInputValue(cents: number | undefined | null): string;
121
+ /**
122
+ * Epoch ms from whatever a timestamp field holds after a round trip — a
123
+ * Firestore `Timestamp`, a `Date` a client just wrote, or a number.
124
+ */
125
+ export declare function timestampMs(value: unknown): number | null;
126
+ /** Whole days a deal has sat in its current stage, never negative. */
127
+ export declare function daysInStage(deal: Pick<CrmDeal, 'stageChangedAtMs' | 'createdAt'>, nowMs: number): number;
128
+ /** A sum per currency, because two currencies never add into one number. */
129
+ export type AmountByCurrency = Record<string, number>;
130
+ export interface BoardSummary {
131
+ /** Deals whose `status` is `open`, whatever stage they sit in. */
132
+ openCount: number;
133
+ /** Every open deal's full amount, per currency. */
134
+ valueByCurrency: AmountByCurrency;
135
+ /** Every open deal's amount times its stage's probability, per currency. */
136
+ weightedByCurrency: AmountByCurrency;
137
+ }
138
+ /**
139
+ * The three figures above the board.
140
+ *
141
+ * Closed deals are excluded from both totals rather than counted at full or
142
+ * zero value: the summary describes what is still in play, and a won deal
143
+ * counted in "pipeline value" would make the pipeline look larger every time
144
+ * something closed. `weightedDealAmountCents` already answers zero for a
145
+ * stage the pipeline no longer has.
146
+ */
147
+ export declare function boardSummary(deals: readonly Pick<CrmDeal, 'status' | 'amountCents' | 'currency' | 'stageId'>[], pipeline: Pick<CrmPipeline, 'stages'> | null | undefined): BoardSummary;
148
+ /** `$1,200.00 · €300.00` — one figure per currency, largest first. */
149
+ export declare function formatAmountByCurrency(totals: AmountByCurrency): string;
150
+ /** The pipeline's stages in `order`, ties broken by position. */
151
+ export declare function sortedStages(pipeline: Pick<CrmPipeline, 'stages'> | null | undefined): CrmDealStage[];
152
+ /** The stages a deal can be dragged between — everything that is not closed. */
153
+ export declare function openStages(pipeline: Pick<CrmPipeline, 'stages'> | null | undefined): CrmDealStage[];
154
+ /** The stage whose `kind` is `won` or `lost`, or null when the pipeline lacks one. */
155
+ export declare function closingStage(pipeline: Pick<CrmPipeline, 'stages'> | null | undefined, kind: 'won' | 'lost'): CrmDealStage | null;
156
+ /**
157
+ * The id a new stage is stored under: the name as a slug, made unique
158
+ * against the stages already there.
159
+ *
160
+ * A slug rather than a random id because the id appears in every deal that
161
+ * sits in the stage and in every automation filter that names it, so a
162
+ * reader looking at `stageId == "demo-booked"` should be able to tell which
163
+ * stage that is without opening the pipeline. Uniqueness is what keeps a
164
+ * second "Demo" from silently becoming the first.
165
+ */
166
+ export declare function newStageId(name: string, existing: readonly CrmDealStage[]): string;
167
+ /**
168
+ * Stages re-numbered 0..n in the order they are GIVEN.
169
+ *
170
+ * Positional on purpose: every caller hands this an array it has already
171
+ * arranged — a swap, a splice, a filter over the sorted stages — and the
172
+ * stored `order` on each entry is the arrangement being replaced. Sorting by
173
+ * it here would put a swapped pair straight back where it was.
174
+ */
175
+ export declare function renumberStages(stages: readonly CrmDealStage[]): CrmDealStage[];
176
+ /** 0–100, whole numbers; anything else becomes the nearest bound. */
177
+ export declare function clampProbability(value: unknown): number;
178
+ /**
179
+ * Add an open stage in front of the closing stages.
180
+ *
181
+ * Won and Lost stay last: a pipeline reads left to right as a progression,
182
+ * and a stage added after "Won" would be a step past the end.
183
+ */
184
+ export declare function addStage(stages: readonly CrmDealStage[], name: string, probability?: number): CrmDealStage[];
185
+ export declare function renameStage(stages: readonly CrmDealStage[], stageId: string, name: string): CrmDealStage[];
186
+ /**
187
+ * Set an OPEN stage's probability. Won is 100 and Lost is 0 by definition —
188
+ * `weightedDealAmountCents` reads the status before the stage, so a Won
189
+ * stage at 60% would change nothing and only mislead the editor.
190
+ */
191
+ export declare function setStageProbability(stages: readonly CrmDealStage[], stageId: string, probability: unknown): CrmDealStage[];
192
+ /**
193
+ * Swap an open stage with its open neighbor. The closing stages are not in
194
+ * the reorderable range, so an open stage can never be moved past Won.
195
+ */
196
+ export declare function moveStage(stages: readonly CrmDealStage[], stageId: string, direction: 'up' | 'down'): CrmDealStage[];
197
+ /**
198
+ * Why a stage cannot be removed, or `null` when it can.
199
+ *
200
+ * `dealsInStage` is the server's count, asked for before this is called: a
201
+ * stage with deals in it cannot go, because every one of those deals would
202
+ * be left pointing at a stage that no longer exists and worth nothing to the
203
+ * forecast. The closing stages cannot go at all — a deal has to be able to
204
+ * be won and lost.
205
+ */
206
+ export declare function stageRemovalRefusal(stages: readonly CrmDealStage[], stageId: string, dealsInStage: number): string | null;
207
+ export declare function removeStage(stages: readonly CrmDealStage[], stageId: string): CrmDealStage[];
208
+ /**
209
+ * What a stored set of stages has to satisfy before it is written back:
210
+ * unique ids, a name on every stage, exactly one Won and one Lost, at least
211
+ * one open stage. The editor refuses a save that fails this rather than
212
+ * writing a pipeline the board cannot draw.
213
+ */
214
+ export declare function stagesProblem(stages: readonly CrmDealStage[]): string | null;
215
+ /**
216
+ * The event a stage change emits, and the flat payload a workflow filter
217
+ * reads (AGL-2598). Strings and numbers only — a workflow expression
218
+ * evaluates over scalars, and an absent link is the empty string rather than
219
+ * a missing key so `contactId == ""` is a filter somebody can write.
220
+ */
221
+ export type DealEventName = 'dealStageChanged' | 'dealWon' | 'dealLost';
222
+ export declare function dealEventName(status: CrmDeal['status']): DealEventName;
223
+ export declare function dealEventPayload(dealId: string, deal: Pick<CrmDeal, 'title' | 'amountCents' | 'currency' | 'stageId' | 'ownerUid' | 'contactId' | 'companyId' | 'lostReason'>, previousStageId: string): Record<string, string | number>;
224
+ /** Initials for an avatar: the first letters of the first two words. */
225
+ export declare function initialsFor(label: string): string;
226
+ /**
227
+ * A stable hue for one person, so an owner keeps one color across cards and
228
+ * sessions. Hashing the label rather than picking from a palette is what
229
+ * makes the same uid the same color on every machine.
230
+ */
231
+ export declare function hueFor(label: string): number;
232
+ /** `2026-09-05` for a date input, from epoch ms; `''` for none. */
233
+ export declare function dateInputValue(ms: number | null | undefined): string;
234
+ /**
235
+ * Epoch ms at local noon of a typed `YYYY-MM-DD`, or `null`.
236
+ *
237
+ * Noon rather than midnight so the day survives a timezone round trip: a
238
+ * close date stored at local midnight and read back one timezone west shows
239
+ * the day before.
240
+ */
241
+ export declare function dateInputMs(value: string): number | null;
@@ -0,0 +1,439 @@
1
+ import { _ as _extends } from "@swc/helpers/_/_extends";
2
+ /**
3
+ * @license
4
+ * Copyright 2026 Aglyn LLC
5
+ *
6
+ * Licensed under the Apache License, Version 2.0 (the "License");
7
+ * you may not use this file except in compliance with the License.
8
+ * You may obtain a copy of the License at
9
+ *
10
+ * http://www.apache.org/licenses/LICENSE-2.0
11
+ *
12
+ * Unless required by applicable law or agreed to in writing, software
13
+ * distributed under the License is distributed on an "AS IS" BASIS,
14
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ * See the License for the specific language governing permissions and
16
+ * limitations under the License.
17
+ */ /**
18
+ * The pipeline's arithmetic and the stage editor's rules (AGL-2598), as pure
19
+ * functions — no Firestore, no React — so the board, the table, the detail
20
+ * page and the server route read one definition of "what is this pipeline
21
+ * worth" and "which stage edits are legal".
22
+ */ // The module itself and never the `@aglyn/aglyn` barrel: this file is
23
+ // reached from the server entry through the deal-stage route, and the barrel
24
+ // carries client-only context modules the App Router graph refuses on a
25
+ // server path (AGL-405/1349).
26
+ import { DEFAULT_DEAL_STAGES, dealStageById, isPipelineArchived, weightedDealAmountCents } from "@aglyn/aglyn/app-utils/crm";
27
+ /** The document id the seeded default pipeline is written under. */ export const DEFAULT_PIPELINE_ID = 'default';
28
+ /** Name of the pipeline every org starts with. */ export const DEFAULT_PIPELINE_NAME = 'Sales';
29
+ export const PIPELINE_NAME_MAX = 60;
30
+ /** The pipelines a picker offers and a new deal may land in: the ones not archived. */ export function activePipelines(pipelines) {
31
+ return pipelines.filter((pipeline)=>!isPipelineArchived(pipeline));
32
+ }
33
+ /**
34
+ * The pipeline a new deal lands in when nobody picks one: the active one
35
+ * marked default, else the first active one, else nothing. An archived
36
+ * pipeline is never the default even if its flag was left on — archiving
37
+ * clears the flag, but a document written by an older console may not
38
+ * have had it cleared, and a default nobody can create a deal in is a
39
+ * board that opens on a pipeline the picker does not list.
40
+ */ export function defaultPipelineOf(pipelines) {
41
+ var _ref, _active_find;
42
+ const active = activePipelines(pipelines);
43
+ return (_ref = (_active_find = active.find((pipeline)=>pipeline.isDefault)) != null ? _active_find : active[0]) != null ? _ref : null;
44
+ }
45
+ /**
46
+ * Why a pipeline cannot be created or renamed to `name`, or `null`.
47
+ *
48
+ * Names are unique among the ACTIVE pipelines, compared without case: the
49
+ * picker lists them by name alone, and two rows reading "Sales" would be a
50
+ * choice nobody can make. An archived pipeline's name is free to reuse —
51
+ * "Sales 2025" retired and "Sales" started over is the point of archiving.
52
+ */ export function pipelineNameProblem(name, pipelines, ownId) {
53
+ const trimmed = String(name != null ? name : '').trim();
54
+ if (!trimmed) return 'A pipeline needs a name.';
55
+ const taken = activePipelines(pipelines).find((pipeline)=>{
56
+ var _pipeline_name;
57
+ return pipeline.$id !== ownId && String((_pipeline_name = pipeline.name) != null ? _pipeline_name : '').trim().toLowerCase() === trimmed.toLowerCase();
58
+ });
59
+ if (taken) return `Another pipeline is already called "${taken.name}".`;
60
+ return null;
61
+ }
62
+ /**
63
+ * Why a pipeline cannot be archived, or `null` when it can.
64
+ *
65
+ * `openDeals` is the server's count, asked for before this is called, the
66
+ * way `stageRemovalRefusal` asks: an open deal in an archived pipeline is
67
+ * a card on no board, and the count is taken at the click because a deal
68
+ * can be created into the pipeline from another tab meanwhile. The default
69
+ * pipeline cannot go while it is the default — a new deal has to land
70
+ * somewhere — and the last active one cannot go at all, for the same
71
+ * reason from the other side.
72
+ */ export function pipelineArchiveRefusal(pipeline, pipelines, openDeals) {
73
+ if (isPipelineArchived(pipeline)) return 'This pipeline is already archived.';
74
+ if (activePipelines(pipelines).filter((entry)=>entry.$id !== pipeline.$id).length === 0) {
75
+ return 'The last pipeline cannot be archived.';
76
+ }
77
+ if (pipeline.isDefault) {
78
+ return 'This is the default pipeline. Make another one the default first.';
79
+ }
80
+ if (openDeals > 0) {
81
+ return `${openDeals.toLocaleString()} open ${openDeals === 1 ? 'deal is' : 'deals are'} ` + 'in this pipeline. Close or move them first, so none is left on a board nobody opens.';
82
+ }
83
+ return null;
84
+ }
85
+ /**
86
+ * The document a new pipeline is created as: the name, a COPY of the
87
+ * default stages, not the default, active. A copy for the reason
88
+ * `DEFAULT_DEAL_STAGES` gives — a second pipeline seeded later must start
89
+ * from the original set, whatever the first one's editor did to its own.
90
+ */ export function newPipelineDocument(name, context) {
91
+ return {
92
+ name: String(name != null ? name : '').trim().slice(0, PIPELINE_NAME_MAX),
93
+ stages: DEFAULT_DEAL_STAGES.map((stage)=>_extends({}, stage)),
94
+ isDefault: false,
95
+ archivedAt: null,
96
+ visibleTo: [
97
+ ...context.visibleTo
98
+ ],
99
+ hostId: context.hostId,
100
+ createdByUid: context.uid,
101
+ createdAt: new Date(context.nowMs),
102
+ updatedAt: new Date(context.nowMs)
103
+ };
104
+ }
105
+ /**
106
+ * Currencies the amount picker offers, lowercase ISO 4217 as the model
107
+ * stores them. Short on purpose: a picker of a hundred and eighty currencies
108
+ * is a scroll, and a deal in one outside this list is entered through the
109
+ * API with whatever code it carries — the display below formats any code
110
+ * `Intl` knows.
111
+ */ export const DEAL_CURRENCIES = [
112
+ 'usd',
113
+ 'eur',
114
+ 'gbp',
115
+ 'cad',
116
+ 'aud',
117
+ 'nzd',
118
+ 'chf',
119
+ 'jpy',
120
+ 'sek',
121
+ 'nok',
122
+ 'dkk',
123
+ 'mxn',
124
+ 'brl',
125
+ 'inr',
126
+ 'sgd'
127
+ ];
128
+ export const DEFAULT_DEAL_CURRENCY = 'usd';
129
+ /** How a deal's `status` reads on screen. */ export const DEAL_STATUS_LABELS = {
130
+ open: 'Open',
131
+ won: 'Won',
132
+ lost: 'Lost'
133
+ };
134
+ /** Cents → the reader's locale, or a plain number when the code is unknown. */ export function formatMoney(cents, currency) {
135
+ const code = String(currency || DEFAULT_DEAL_CURRENCY).toUpperCase();
136
+ const amount = (Number(cents) || 0) / 100;
137
+ try {
138
+ return new Intl.NumberFormat(undefined, {
139
+ style: 'currency',
140
+ currency: code
141
+ }).format(amount);
142
+ } catch (unused) {
143
+ return `${amount.toFixed(2)} ${code}`;
144
+ }
145
+ }
146
+ /**
147
+ * A typed amount, as cents, or `null` when it is not a number.
148
+ *
149
+ * Accepts what people paste from an invoice — a thousands separator, a
150
+ * currency symbol, surrounding space — and refuses a negative: a deal is
151
+ * worth zero or more, and a negative amount here is a typo rather than a
152
+ * refund. Rounded rather than truncated so `19.995` does not lose a cent.
153
+ */ export function parseAmountInput(input) {
154
+ const cleaned = String(input != null ? input : '').replace(/[^0-9.-]/g, '').trim();
155
+ if (!cleaned) return null;
156
+ const value = Number(cleaned);
157
+ if (!Number.isFinite(value) || value < 0) return null;
158
+ return Math.round(value * 100);
159
+ }
160
+ /** Cents → the string the amount field shows, `''` for nothing. */ export function amountInputValue(cents) {
161
+ if (typeof cents !== 'number' || !Number.isFinite(cents)) return '';
162
+ return (cents / 100).toFixed(2);
163
+ }
164
+ /**
165
+ * Epoch ms from whatever a timestamp field holds after a round trip — a
166
+ * Firestore `Timestamp`, a `Date` a client just wrote, or a number.
167
+ */ export function timestampMs(value) {
168
+ if (!value) return null;
169
+ if (typeof value === 'number') return Number.isFinite(value) ? value : null;
170
+ if (value instanceof Date) return value.getTime();
171
+ const seconds = value.seconds;
172
+ if (typeof seconds === 'number') return seconds * 1000;
173
+ const toMillis = value.toMillis;
174
+ if (typeof toMillis === 'function') return toMillis.call(value);
175
+ return null;
176
+ }
177
+ /** Whole days a deal has sat in its current stage, never negative. */ export function daysInStage(deal, nowMs) {
178
+ const since = typeof deal.stageChangedAtMs === 'number' ? deal.stageChangedAtMs : timestampMs(deal.createdAt);
179
+ if (!since) return 0;
180
+ return Math.max(0, Math.floor((nowMs - since) / 86400000));
181
+ }
182
+ function addAmount(totals, currency, cents) {
183
+ var _totals_code;
184
+ const code = String(currency || DEFAULT_DEAL_CURRENCY).toLowerCase();
185
+ totals[code] = ((_totals_code = totals[code]) != null ? _totals_code : 0) + cents;
186
+ }
187
+ /**
188
+ * The three figures above the board.
189
+ *
190
+ * Closed deals are excluded from both totals rather than counted at full or
191
+ * zero value: the summary describes what is still in play, and a won deal
192
+ * counted in "pipeline value" would make the pipeline look larger every time
193
+ * something closed. `weightedDealAmountCents` already answers zero for a
194
+ * stage the pipeline no longer has.
195
+ */ export function boardSummary(deals, pipeline) {
196
+ const summary = {
197
+ openCount: 0,
198
+ valueByCurrency: {},
199
+ weightedByCurrency: {}
200
+ };
201
+ for (const deal of deals){
202
+ var _deal_amountCents;
203
+ if (deal.status !== 'open') continue;
204
+ summary.openCount += 1;
205
+ const amount = Math.max(0, Math.round(Number((_deal_amountCents = deal.amountCents) != null ? _deal_amountCents : 0) || 0));
206
+ addAmount(summary.valueByCurrency, deal.currency, amount);
207
+ addAmount(summary.weightedByCurrency, deal.currency, weightedDealAmountCents(deal, dealStageById(pipeline, deal.stageId)));
208
+ }
209
+ return summary;
210
+ }
211
+ /** `$1,200.00 · €300.00` — one figure per currency, largest first. */ export function formatAmountByCurrency(totals) {
212
+ const entries = Object.entries(totals).sort((a, b)=>b[1] - a[1]);
213
+ if (!entries.length) return formatMoney(0, DEFAULT_DEAL_CURRENCY);
214
+ return entries.map(([code, cents])=>formatMoney(cents, code)).join(' · ');
215
+ }
216
+ /** The pipeline's stages in `order`, ties broken by position. */ export function sortedStages(pipeline) {
217
+ var _ref;
218
+ return [
219
+ ...(_ref = pipeline == null ? void 0 : pipeline.stages) != null ? _ref : []
220
+ ].map((stage, index)=>({
221
+ stage,
222
+ index
223
+ })).sort((a, b)=>a.stage.order - b.stage.order || a.index - b.index).map(({ stage })=>stage);
224
+ }
225
+ /** The stages a deal can be dragged between — everything that is not closed. */ export function openStages(pipeline) {
226
+ return sortedStages(pipeline).filter((stage)=>stage.kind === 'open');
227
+ }
228
+ /** The stage whose `kind` is `won` or `lost`, or null when the pipeline lacks one. */ export function closingStage(pipeline, kind) {
229
+ var _sortedStages_find;
230
+ return (_sortedStages_find = sortedStages(pipeline).find((stage)=>stage.kind === kind)) != null ? _sortedStages_find : null;
231
+ }
232
+ /**
233
+ * The id a new stage is stored under: the name as a slug, made unique
234
+ * against the stages already there.
235
+ *
236
+ * A slug rather than a random id because the id appears in every deal that
237
+ * sits in the stage and in every automation filter that names it, so a
238
+ * reader looking at `stageId == "demo-booked"` should be able to tell which
239
+ * stage that is without opening the pipeline. Uniqueness is what keeps a
240
+ * second "Demo" from silently becoming the first.
241
+ */ export function newStageId(name, existing) {
242
+ const base = String(name != null ? name : '').trim().toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/^-+|-+$/g, '').slice(0, 40) || 'stage';
243
+ const taken = new Set(existing.map((stage)=>stage.id));
244
+ if (!taken.has(base)) return base;
245
+ let suffix = 2;
246
+ while(taken.has(`${base}-${suffix}`))suffix += 1;
247
+ return `${base}-${suffix}`;
248
+ }
249
+ /**
250
+ * Stages re-numbered 0..n in the order they are GIVEN.
251
+ *
252
+ * Positional on purpose: every caller hands this an array it has already
253
+ * arranged — a swap, a splice, a filter over the sorted stages — and the
254
+ * stored `order` on each entry is the arrangement being replaced. Sorting by
255
+ * it here would put a swapped pair straight back where it was.
256
+ */ export function renumberStages(stages) {
257
+ return stages.map((stage, order)=>_extends({}, stage, {
258
+ order
259
+ }));
260
+ }
261
+ /** 0–100, whole numbers; anything else becomes the nearest bound. */ export function clampProbability(value) {
262
+ const number = Math.round(Number(value));
263
+ if (!Number.isFinite(number)) return 0;
264
+ return Math.min(100, Math.max(0, number));
265
+ }
266
+ /**
267
+ * Add an open stage in front of the closing stages.
268
+ *
269
+ * Won and Lost stay last: a pipeline reads left to right as a progression,
270
+ * and a stage added after "Won" would be a step past the end.
271
+ */ export function addStage(stages, name, probability = 50) {
272
+ const trimmed = String(name != null ? name : '').trim();
273
+ if (!trimmed) return [
274
+ ...stages
275
+ ];
276
+ const sorted = sortedStages({
277
+ stages: [
278
+ ...stages
279
+ ]
280
+ });
281
+ const firstClosed = sorted.findIndex((stage)=>stage.kind !== 'open');
282
+ const at = firstClosed === -1 ? sorted.length : firstClosed;
283
+ const stage = {
284
+ id: newStageId(trimmed, sorted),
285
+ name: trimmed,
286
+ order: at,
287
+ probability: clampProbability(probability),
288
+ kind: 'open'
289
+ };
290
+ sorted.splice(at, 0, stage);
291
+ return renumberStages(sorted);
292
+ }
293
+ export function renameStage(stages, stageId, name) {
294
+ const trimmed = String(name != null ? name : '').trim();
295
+ return stages.map((stage)=>stage.id === stageId && trimmed ? _extends({}, stage, {
296
+ name: trimmed
297
+ }) : stage);
298
+ }
299
+ /**
300
+ * Set an OPEN stage's probability. Won is 100 and Lost is 0 by definition —
301
+ * `weightedDealAmountCents` reads the status before the stage, so a Won
302
+ * stage at 60% would change nothing and only mislead the editor.
303
+ */ export function setStageProbability(stages, stageId, probability) {
304
+ return stages.map((stage)=>stage.id === stageId && stage.kind === 'open' ? _extends({}, stage, {
305
+ probability: clampProbability(probability)
306
+ }) : stage);
307
+ }
308
+ /**
309
+ * Swap an open stage with its open neighbor. The closing stages are not in
310
+ * the reorderable range, so an open stage can never be moved past Won.
311
+ */ export function moveStage(stages, stageId, direction) {
312
+ const sorted = sortedStages({
313
+ stages: [
314
+ ...stages
315
+ ]
316
+ });
317
+ const index = sorted.findIndex((stage)=>stage.id === stageId);
318
+ if (index === -1 || sorted[index].kind !== 'open') return sorted;
319
+ const target = direction === 'up' ? index - 1 : index + 1;
320
+ if (target < 0 || target >= sorted.length) return sorted;
321
+ if (sorted[target].kind !== 'open') return sorted;
322
+ const swapped = [
323
+ ...sorted
324
+ ];
325
+ const moving = swapped[index];
326
+ swapped[index] = swapped[target];
327
+ swapped[target] = moving;
328
+ return renumberStages(swapped);
329
+ }
330
+ /**
331
+ * Why a stage cannot be removed, or `null` when it can.
332
+ *
333
+ * `dealsInStage` is the server's count, asked for before this is called: a
334
+ * stage with deals in it cannot go, because every one of those deals would
335
+ * be left pointing at a stage that no longer exists and worth nothing to the
336
+ * forecast. The closing stages cannot go at all — a deal has to be able to
337
+ * be won and lost.
338
+ */ export function stageRemovalRefusal(stages, stageId, dealsInStage) {
339
+ const stage = stages.find((entry)=>entry.id === stageId);
340
+ if (!stage) return 'This stage is no longer in the pipeline.';
341
+ if (stage.kind !== 'open') {
342
+ return `Every pipeline keeps its ${stage.kind === 'won' ? 'Won' : 'Lost'} stage.`;
343
+ }
344
+ if (openStages({
345
+ stages: [
346
+ ...stages
347
+ ]
348
+ }).length <= 1) {
349
+ return 'A pipeline needs at least one open stage.';
350
+ }
351
+ if (dealsInStage > 0) {
352
+ return `${dealsInStage.toLocaleString()} ${dealsInStage === 1 ? 'deal is' : 'deals are'} ` + 'in this stage. Move them first, so none is left in a stage that no longer exists.';
353
+ }
354
+ return null;
355
+ }
356
+ export function removeStage(stages, stageId) {
357
+ return renumberStages(stages.filter((stage)=>stage.id !== stageId));
358
+ }
359
+ /**
360
+ * What a stored set of stages has to satisfy before it is written back:
361
+ * unique ids, a name on every stage, exactly one Won and one Lost, at least
362
+ * one open stage. The editor refuses a save that fails this rather than
363
+ * writing a pipeline the board cannot draw.
364
+ */ export function stagesProblem(stages) {
365
+ if (!stages.length) return 'A pipeline needs stages.';
366
+ const ids = new Set();
367
+ for (const stage of stages){
368
+ var _stage_name;
369
+ if (!stage.id) return 'Every stage needs an id.';
370
+ if (ids.has(stage.id)) return `Two stages share the id "${stage.id}".`;
371
+ ids.add(stage.id);
372
+ if (!String((_stage_name = stage.name) != null ? _stage_name : '').trim()) return 'Every stage needs a name.';
373
+ }
374
+ const won = stages.filter((stage)=>stage.kind === 'won').length;
375
+ const lost = stages.filter((stage)=>stage.kind === 'lost').length;
376
+ if (won !== 1) return 'A pipeline has exactly one Won stage.';
377
+ if (lost !== 1) return 'A pipeline has exactly one Lost stage.';
378
+ if (!stages.some((stage)=>stage.kind === 'open')) {
379
+ return 'A pipeline needs at least one open stage.';
380
+ }
381
+ return null;
382
+ }
383
+ export function dealEventName(status) {
384
+ if (status === 'won') return 'dealWon';
385
+ if (status === 'lost') return 'dealLost';
386
+ return 'dealStageChanged';
387
+ }
388
+ export function dealEventPayload(dealId, deal, previousStageId) {
389
+ var _deal_title, _deal_amountCents, _deal_stageId, _deal_ownerUid, _deal_contactId, _deal_companyId;
390
+ return _extends({
391
+ dealId,
392
+ title: String((_deal_title = deal.title) != null ? _deal_title : ''),
393
+ amountCents: Math.max(0, Math.round(Number((_deal_amountCents = deal.amountCents) != null ? _deal_amountCents : 0) || 0)),
394
+ currency: String(deal.currency || DEFAULT_DEAL_CURRENCY).toLowerCase(),
395
+ stageId: String((_deal_stageId = deal.stageId) != null ? _deal_stageId : ''),
396
+ previousStageId: String(previousStageId != null ? previousStageId : ''),
397
+ ownerUid: String((_deal_ownerUid = deal.ownerUid) != null ? _deal_ownerUid : ''),
398
+ contactId: String((_deal_contactId = deal.contactId) != null ? _deal_contactId : ''),
399
+ companyId: String((_deal_companyId = deal.companyId) != null ? _deal_companyId : '')
400
+ }, deal.lostReason ? {
401
+ lostReason: String(deal.lostReason)
402
+ } : {});
403
+ }
404
+ /** Initials for an avatar: the first letters of the first two words. */ export function initialsFor(label) {
405
+ const words = String(label != null ? label : '').trim().split(/[\s@._-]+/).filter(Boolean);
406
+ const letters = words.slice(0, 2).map((word)=>word[0]).join('');
407
+ return (letters || '?').toUpperCase();
408
+ }
409
+ /**
410
+ * A stable hue for one person, so an owner keeps one color across cards and
411
+ * sessions. Hashing the label rather than picking from a palette is what
412
+ * makes the same uid the same color on every machine.
413
+ */ export function hueFor(label) {
414
+ let hash = 0;
415
+ for(let index = 0; index < label.length; index += 1){
416
+ hash = (hash * 31 + label.charCodeAt(index)) % 360;
417
+ }
418
+ return hash;
419
+ }
420
+ /** `2026-09-05` for a date input, from epoch ms; `''` for none. */ export function dateInputValue(ms) {
421
+ if (typeof ms !== 'number' || !Number.isFinite(ms)) return '';
422
+ const at = new Date(ms);
423
+ const offset = at.getTimezoneOffset() * 60000;
424
+ return new Date(ms - offset).toISOString().slice(0, 10);
425
+ }
426
+ /**
427
+ * Epoch ms at local noon of a typed `YYYY-MM-DD`, or `null`.
428
+ *
429
+ * Noon rather than midnight so the day survives a timezone round trip: a
430
+ * close date stored at local midnight and read back one timezone west shows
431
+ * the day before.
432
+ */ export function dateInputMs(value) {
433
+ const match = /^(\d{4})-(\d{2})-(\d{2})$/.exec(String(value != null ? value : '').trim());
434
+ if (!match) return null;
435
+ const at = new Date(Number(match[1]), Number(match[2]) - 1, Number(match[3]), 12, 0, 0, 0);
436
+ return Number.isNaN(at.getTime()) ? null : at.getTime();
437
+ }
438
+
439
+ //# sourceMappingURL=deal-board-model.js.map