@aglyn/plugins-crm 1.0.0-beta.221 → 1.0.0-beta.223

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 (541) hide show
  1. package/README.md +2 -1
  2. package/package.json +13 -13
  3. package/src/lib/components/activity-list.js +12 -5
  4. package/src/lib/components/activity-list.js.map +1 -1
  5. package/src/lib/components/companies-bulk-bar.d.ts +1 -4
  6. package/src/lib/components/companies-bulk-bar.js +7 -20
  7. package/src/lib/components/companies-bulk-bar.js.map +1 -1
  8. package/src/lib/components/companies-section.d.ts +3 -3
  9. package/src/lib/components/companies-section.js +149 -46
  10. package/src/lib/components/companies-section.js.map +1 -1
  11. package/src/lib/components/company-edit-drawer.js +281 -20
  12. package/src/lib/components/company-edit-drawer.js.map +1 -1
  13. package/src/lib/components/company-properties-card.js +99 -8
  14. package/src/lib/components/company-properties-card.js.map +1 -1
  15. package/src/lib/components/contact-detail-page.js +3 -1
  16. package/src/lib/components/contact-detail-page.js.map +1 -1
  17. package/src/lib/components/contact-merge-dialog.js +33 -10
  18. package/src/lib/components/contact-merge-dialog.js.map +1 -1
  19. package/src/lib/components/contact-properties-card.d.ts +0 -69
  20. package/src/lib/components/contact-properties-card.js +350 -60
  21. package/src/lib/components/contact-properties-card.js.map +1 -1
  22. package/src/lib/components/contact-reports-to-field.d.ts +46 -0
  23. package/src/lib/components/contact-reports-to-field.js +67 -0
  24. package/src/lib/components/contact-reports-to-field.js.map +1 -0
  25. package/src/lib/components/contacts-bulk-bar.d.ts +1 -8
  26. package/src/lib/components/contacts-bulk-bar.js +7 -19
  27. package/src/lib/components/contacts-bulk-bar.js.map +1 -1
  28. package/src/lib/components/contacts-section.js +46 -33
  29. package/src/lib/components/contacts-section.js.map +1 -1
  30. package/src/lib/components/crm-call-actions.d.ts +10 -0
  31. package/src/lib/components/crm-call-actions.js +26 -9
  32. package/src/lib/components/crm-call-actions.js.map +1 -1
  33. package/src/lib/components/crm-next-activity-column.js +1 -1
  34. package/src/lib/components/crm-next-activity-column.js.map +1 -1
  35. package/src/lib/components/crm-record-picker.d.ts +15 -0
  36. package/src/lib/components/crm-record-picker.js +16 -10
  37. package/src/lib/components/crm-record-picker.js.map +1 -1
  38. package/src/lib/components/crm-transfer-buttons.d.ts +54 -0
  39. package/src/lib/components/crm-transfer-buttons.js +167 -0
  40. package/src/lib/components/crm-transfer-buttons.js.map +1 -0
  41. package/src/lib/components/deal-contact-roles-card.d.ts +46 -0
  42. package/src/lib/components/deal-contact-roles-card.js +368 -0
  43. package/src/lib/components/deal-contact-roles-card.js.map +1 -0
  44. package/src/lib/components/deal-detail-page.d.ts +3 -2
  45. package/src/lib/components/deal-detail-page.js +25 -6
  46. package/src/lib/components/deal-detail-page.js.map +1 -1
  47. package/src/lib/components/deal-edit-drawer.d.ts +10 -0
  48. package/src/lib/components/deal-edit-drawer.js +219 -10
  49. package/src/lib/components/deal-edit-drawer.js.map +1 -1
  50. package/src/lib/components/deal-properties-card.d.ts +7 -0
  51. package/src/lib/components/deal-properties-card.js +34 -3
  52. package/src/lib/components/deal-properties-card.js.map +1 -1
  53. package/src/lib/components/deal-stage-card.d.ts +4 -0
  54. package/src/lib/components/deal-stage-card.js +10 -2
  55. package/src/lib/components/deal-stage-card.js.map +1 -1
  56. package/src/lib/components/deals-bulk-bar.d.ts +0 -3
  57. package/src/lib/components/deals-bulk-bar.js +7 -20
  58. package/src/lib/components/deals-bulk-bar.js.map +1 -1
  59. package/src/lib/components/deals-section.d.ts +3 -3
  60. package/src/lib/components/deals-section.js +123 -63
  61. package/src/lib/components/deals-section.js.map +1 -1
  62. package/src/lib/components/fields-section.js +31 -17
  63. package/src/lib/components/fields-section.js.map +1 -1
  64. package/src/lib/components/lead-convert-dialog.d.ts +4 -0
  65. package/src/lib/components/lead-convert-dialog.js +23 -1
  66. package/src/lib/components/lead-convert-dialog.js.map +1 -1
  67. package/src/lib/components/lead-detail-page.js +8 -2
  68. package/src/lib/components/lead-detail-page.js.map +1 -1
  69. package/src/lib/components/lead-profile-fields.d.ts +71 -0
  70. package/src/lib/components/lead-profile-fields.js +386 -0
  71. package/src/lib/components/lead-profile-fields.js.map +1 -0
  72. package/src/lib/components/lead-properties-card.d.ts +2 -1
  73. package/src/lib/components/lead-properties-card.js +85 -176
  74. package/src/lib/components/lead-properties-card.js.map +1 -1
  75. package/src/lib/components/lead-source-select.d.ts +4 -23
  76. package/src/lib/components/lead-source-select.js +9 -73
  77. package/src/lib/components/lead-source-select.js.map +1 -1
  78. package/src/lib/components/lead-status-chip.d.ts +9 -3
  79. package/src/lib/components/lead-status-chip.js +8 -4
  80. package/src/lib/components/lead-status-chip.js.map +1 -1
  81. package/src/lib/components/lead-status-options.d.ts +20 -0
  82. package/src/lib/components/lead-status-options.js +51 -0
  83. package/src/lib/components/lead-status-options.js.map +1 -0
  84. package/src/lib/components/lead-unqualify-dialog.d.ts +5 -0
  85. package/src/lib/components/lead-unqualify-dialog.js +50 -18
  86. package/src/lib/components/lead-unqualify-dialog.js.map +1 -1
  87. package/src/lib/components/leads-bulk-bar.d.ts +0 -3
  88. package/src/lib/components/leads-bulk-bar.js +29 -29
  89. package/src/lib/components/leads-bulk-bar.js.map +1 -1
  90. package/src/lib/components/leads-section.js +120 -68
  91. package/src/lib/components/leads-section.js.map +1 -1
  92. package/src/lib/components/linked-deals-card.d.ts +4 -0
  93. package/src/lib/components/linked-deals-card.js +47 -3
  94. package/src/lib/components/linked-deals-card.js.map +1 -1
  95. package/src/lib/components/log-activity-dialog.js +43 -3
  96. package/src/lib/components/log-activity-dialog.js.map +1 -1
  97. package/src/lib/components/new-contact-drawer.d.ts +8 -0
  98. package/src/lib/components/new-contact-drawer.js +108 -6
  99. package/src/lib/components/new-contact-drawer.js.map +1 -1
  100. package/src/lib/components/new-lead-drawer.d.ts +9 -2
  101. package/src/lib/components/new-lead-drawer.js +88 -121
  102. package/src/lib/components/new-lead-drawer.js.map +1 -1
  103. package/src/lib/components/picklist-select.d.ts +36 -0
  104. package/src/lib/components/picklist-select.js +114 -0
  105. package/src/lib/components/picklist-select.js.map +1 -0
  106. package/src/lib/components/picklist-values-card.d.ts +34 -0
  107. package/src/lib/components/{lead-source-values-card.js → picklist-values-card.js} +241 -58
  108. package/src/lib/components/picklist-values-card.js.map +1 -0
  109. package/src/lib/components/pipeline-stages-dialog.d.ts +7 -0
  110. package/src/lib/components/pipeline-stages-dialog.js +26 -4
  111. package/src/lib/components/pipeline-stages-dialog.js.map +1 -1
  112. package/src/lib/components/pipelines-dialog.js +15 -6
  113. package/src/lib/components/pipelines-dialog.js.map +1 -1
  114. package/src/lib/components/recent-activity-feed.js +20 -5
  115. package/src/lib/components/recent-activity-feed.js.map +1 -1
  116. package/src/lib/components/recipes-card.js +4 -2
  117. package/src/lib/components/recipes-card.js.map +1 -1
  118. package/src/lib/components/record-tasks-card.js +15 -8
  119. package/src/lib/components/record-tasks-card.js.map +1 -1
  120. package/src/lib/components/reports/forecast-card.d.ts +6 -0
  121. package/src/lib/components/reports/forecast-card.js +101 -3
  122. package/src/lib/components/reports/forecast-card.js.map +1 -1
  123. package/src/lib/components/reports/lead-funnel-card.d.ts +12 -0
  124. package/src/lib/components/reports/lead-funnel-card.js +9 -5
  125. package/src/lib/components/reports/lead-funnel-card.js.map +1 -1
  126. package/src/lib/components/reports/lead-source-card.d.ts +23 -0
  127. package/src/lib/components/reports/lead-source-card.js +318 -0
  128. package/src/lib/components/reports/lead-source-card.js.map +1 -0
  129. package/src/lib/components/reports/pipeline-card.js +2 -1
  130. package/src/lib/components/reports/pipeline-card.js.map +1 -1
  131. package/src/lib/components/reports/report-export.js +1 -1
  132. package/src/lib/components/reports/report-export.js.map +1 -1
  133. package/src/lib/components/reports-section.js +8 -0
  134. package/src/lib/components/reports-section.js.map +1 -1
  135. package/src/lib/components/sharing-rule-drawer.d.ts +5 -0
  136. package/src/lib/components/sharing-rule-drawer.js +108 -19
  137. package/src/lib/components/sharing-rule-drawer.js.map +1 -1
  138. package/src/lib/components/sharing-rules-card.js +11 -3
  139. package/src/lib/components/sharing-rules-card.js.map +1 -1
  140. package/src/lib/components/task-cells.d.ts +9 -1
  141. package/src/lib/components/task-cells.js +9 -4
  142. package/src/lib/components/task-cells.js.map +1 -1
  143. package/src/lib/components/task-edit-drawer.js +111 -43
  144. package/src/lib/components/task-edit-drawer.js.map +1 -1
  145. package/src/lib/components/tasks-bulk-bar.d.ts +0 -3
  146. package/src/lib/components/tasks-bulk-bar.js +7 -20
  147. package/src/lib/components/tasks-bulk-bar.js.map +1 -1
  148. package/src/lib/components/tasks-calendar.d.ts +3 -0
  149. package/src/lib/components/tasks-calendar.js +8 -1
  150. package/src/lib/components/tasks-calendar.js.map +1 -1
  151. package/src/lib/components/tasks-section.d.ts +3 -3
  152. package/src/lib/components/tasks-section.js +58 -43
  153. package/src/lib/components/tasks-section.js.map +1 -1
  154. package/src/lib/constants/api-routes.d.ts +2 -9
  155. package/src/lib/constants/api-routes.js +1 -7
  156. package/src/lib/constants/api-routes.js.map +1 -1
  157. package/src/lib/constants/bundle-common.d.ts +6 -0
  158. package/src/lib/constants/bundle-common.js +11 -0
  159. package/src/lib/constants/bundle-common.js.map +1 -1
  160. package/src/lib/constants/company-filters.d.ts +14 -0
  161. package/src/lib/constants/company-filters.js +51 -1
  162. package/src/lib/constants/company-filters.js.map +1 -1
  163. package/src/lib/constants/contact-filters.d.ts +2 -0
  164. package/src/lib/constants/contact-filters.js +18 -1
  165. package/src/lib/constants/contact-filters.js.map +1 -1
  166. package/src/lib/constants/deal-filters.d.ts +22 -1
  167. package/src/lib/constants/deal-filters.js +67 -4
  168. package/src/lib/constants/deal-filters.js.map +1 -1
  169. package/src/lib/declarations.console-server.d.ts +3 -0
  170. package/src/lib/declarations.console-server.js +35 -0
  171. package/src/lib/declarations.console-server.js.map +1 -1
  172. package/src/lib/declarations.d.ts +26 -0
  173. package/src/lib/declarations.js +35 -0
  174. package/src/lib/declarations.js.map +1 -0
  175. package/src/lib/declarations.server.d.ts +11 -0
  176. package/src/lib/declarations.server.js +97 -1
  177. package/src/lib/declarations.server.js.map +1 -1
  178. package/src/lib/hooks/use-company-picklists.d.ts +15 -0
  179. package/src/lib/hooks/use-company-picklists.js +55 -0
  180. package/src/lib/hooks/use-company-picklists.js.map +1 -0
  181. package/src/lib/hooks/use-crm-picklist.d.ts +25 -0
  182. package/src/lib/hooks/use-crm-picklist.js +53 -0
  183. package/src/lib/hooks/use-crm-picklist.js.map +1 -0
  184. package/src/lib/hooks/use-crm-record-names.d.ts +16 -0
  185. package/src/lib/hooks/use-crm-record-names.js +45 -19
  186. package/src/lib/hooks/use-crm-record-names.js.map +1 -1
  187. package/src/lib/hooks/use-crm-task-picklists.d.ts +11 -0
  188. package/src/lib/hooks/use-crm-task-picklists.js +45 -0
  189. package/src/lib/hooks/use-crm-task-picklists.js.map +1 -0
  190. package/src/lib/hooks/use-deals.d.ts +14 -0
  191. package/src/lib/hooks/use-deals.js +29 -0
  192. package/src/lib/hooks/use-deals.js.map +1 -1
  193. package/src/lib/hooks/use-lead-picklists.d.ts +14 -0
  194. package/src/lib/hooks/use-lead-picklists.js +46 -0
  195. package/src/lib/hooks/use-lead-picklists.js.map +1 -0
  196. package/src/lib/hooks/use-lead-source-picklist.d.ts +5 -19
  197. package/src/lib/hooks/use-lead-source-picklist.js +12 -22
  198. package/src/lib/hooks/use-lead-source-picklist.js.map +1 -1
  199. package/src/lib/hooks/use-lead-status-picklist.d.ts +9 -0
  200. package/src/lib/hooks/use-lead-status-picklist.js +40 -0
  201. package/src/lib/hooks/use-lead-status-picklist.js.map +1 -0
  202. package/src/lib/model/companies.d.ts +32 -3
  203. package/src/lib/model/companies.js +133 -16
  204. package/src/lib/model/companies.js.map +1 -1
  205. package/src/lib/model/contact-merge.d.ts +27 -3
  206. package/src/lib/model/contact-merge.js +81 -7
  207. package/src/lib/model/contact-merge.js.map +1 -1
  208. package/src/lib/model/contact-record.d.ts +17 -0
  209. package/src/lib/model/contact-record.js +17 -2
  210. package/src/lib/model/contact-record.js.map +1 -1
  211. package/src/lib/model/contact-update.d.ts +31 -2
  212. package/src/lib/model/contact-update.js +14 -0
  213. package/src/lib/model/contact-update.js.map +1 -1
  214. package/src/lib/model/crm-list-query.d.ts +5 -0
  215. package/src/lib/model/crm-list-query.js +8 -0
  216. package/src/lib/model/crm-list-query.js.map +1 -1
  217. package/src/lib/model/crm-next-activity.d.ts +107 -0
  218. package/src/lib/model/crm-next-activity.js +140 -0
  219. package/src/lib/model/crm-next-activity.js.map +1 -0
  220. package/src/lib/model/crm-recipes.d.ts +40 -0
  221. package/src/lib/model/crm-recipes.js +259 -0
  222. package/src/lib/model/crm-recipes.js.map +1 -0
  223. package/src/lib/model/crm-record-counts.d.ts +36 -0
  224. package/src/lib/model/crm-record-counts.js +54 -0
  225. package/src/lib/model/crm-record-counts.js.map +1 -0
  226. package/src/lib/model/crm-record-lists.d.ts +23 -0
  227. package/src/lib/model/crm-record-lists.js +161 -0
  228. package/src/lib/model/crm-record-lists.js.map +1 -0
  229. package/src/lib/model/crm-reports.d.ts +73 -3
  230. package/src/lib/model/crm-reports.js +120 -1
  231. package/src/lib/model/crm-reports.js.map +1 -1
  232. package/src/lib/model/crm-sharing.d.ts +21 -3
  233. package/src/lib/model/crm-sharing.js +27 -6
  234. package/src/lib/model/crm-sharing.js.map +1 -1
  235. package/src/lib/model/crm-task-reminders.d.ts +152 -0
  236. package/src/lib/model/crm-task-reminders.js +161 -0
  237. package/src/lib/model/crm-task-reminders.js.map +1 -0
  238. package/src/lib/model/deal-board-model.d.ts +8 -2
  239. package/src/lib/model/deal-board-model.js +15 -2
  240. package/src/lib/model/deal-board-model.js.map +1 -1
  241. package/src/lib/model/deal-contact-roles.d.ts +45 -0
  242. package/src/lib/model/deal-contact-roles.js +73 -0
  243. package/src/lib/model/deal-contact-roles.js.map +1 -0
  244. package/src/lib/model/deal-form-model.d.ts +56 -0
  245. package/src/lib/model/deal-form-model.js +79 -7
  246. package/src/lib/model/deal-form-model.js.map +1 -1
  247. package/src/lib/model/download-text-file.d.ts +23 -0
  248. package/src/lib/model/download-text-file.js +34 -0
  249. package/src/lib/model/download-text-file.js.map +1 -0
  250. package/src/lib/model/lead-filters.d.ts +36 -2
  251. package/src/lib/model/lead-filters.js +123 -2
  252. package/src/lib/model/lead-filters.js.map +1 -1
  253. package/src/lib/model/lead-source-direction.d.ts +38 -0
  254. package/src/lib/model/lead-source-direction.js +52 -0
  255. package/src/lib/model/lead-source-direction.js.map +1 -0
  256. package/src/lib/model/next-activity.d.ts +1 -1
  257. package/src/lib/model/next-activity.js.map +1 -1
  258. package/src/lib/model/picklist-values.d.ts +119 -0
  259. package/src/lib/model/picklist-values.js +256 -0
  260. package/src/lib/model/picklist-values.js.map +1 -0
  261. package/src/lib/model/record-facts-disclosed.d.ts +81 -0
  262. package/src/lib/model/record-facts-disclosed.js +281 -0
  263. package/src/lib/model/record-facts-disclosed.js.map +1 -0
  264. package/src/lib/model/record-facts.d.ts +215 -34
  265. package/src/lib/model/record-facts.js +307 -128
  266. package/src/lib/model/record-facts.js.map +1 -1
  267. package/src/lib/model/task-picklists.d.ts +52 -0
  268. package/src/lib/model/task-picklists.js +83 -0
  269. package/src/lib/model/task-picklists.js.map +1 -0
  270. package/src/lib/model/task-routes.d.ts +13 -0
  271. package/src/lib/model/task-routes.js +23 -4
  272. package/src/lib/model/task-routes.js.map +1 -1
  273. package/src/lib/plan-entitlements.js +6 -4
  274. package/src/lib/plan-entitlements.js.map +1 -1
  275. package/src/lib/plugin.js +17 -0
  276. package/src/lib/plugin.js.map +1 -1
  277. package/src/lib/server/api-v1/contacts.js +220 -14
  278. package/src/lib/server/api-v1/contacts.js.map +1 -1
  279. package/src/lib/server/api-v1/crm-activities.js +14 -1
  280. package/src/lib/server/api-v1/crm-activities.js.map +1 -1
  281. package/src/lib/server/api-v1/crm-companies.js +123 -14
  282. package/src/lib/server/api-v1/crm-companies.js.map +1 -1
  283. package/src/lib/server/api-v1/crm-deals.js +291 -26
  284. package/src/lib/server/api-v1/crm-deals.js.map +1 -1
  285. package/src/lib/server/api-v1/crm-leads.js +144 -38
  286. package/src/lib/server/api-v1/crm-leads.js.map +1 -1
  287. package/src/lib/server/api-v1/crm-pipelines.d.ts +6 -0
  288. package/src/lib/server/api-v1/crm-pipelines.js +8 -2
  289. package/src/lib/server/api-v1/crm-pipelines.js.map +1 -1
  290. package/src/lib/server/api-v1/crm-tasks.js +78 -34
  291. package/src/lib/server/api-v1/crm-tasks.js.map +1 -1
  292. package/src/lib/server/api-v1/openapi.d.ts +0 -11
  293. package/src/lib/server/api-v1/openapi.js +171 -16
  294. package/src/lib/server/api-v1/openapi.js.map +1 -1
  295. package/src/lib/server/assign-contact-owner.d.ts +188 -0
  296. package/src/lib/server/assign-contact-owner.js +446 -0
  297. package/src/lib/server/assign-contact-owner.js.map +1 -0
  298. package/src/lib/server/associate-company-by-domain.d.ts +70 -0
  299. package/src/lib/server/associate-company-by-domain.js +153 -0
  300. package/src/lib/server/associate-company-by-domain.js.map +1 -0
  301. package/src/lib/server/automation-steps.d.ts +140 -0
  302. package/src/lib/server/automation-steps.js +669 -0
  303. package/src/lib/server/automation-steps.js.map +1 -0
  304. package/src/lib/server/capture-contact.d.ts +17 -0
  305. package/src/lib/server/capture-contact.js +95 -26
  306. package/src/lib/server/capture-contact.js.map +1 -1
  307. package/src/lib/server/capture-host-contact.d.ts +104 -0
  308. package/src/lib/server/capture-host-contact.js +151 -0
  309. package/src/lib/server/capture-host-contact.js.map +1 -0
  310. package/src/lib/server/company-children.d.ts +25 -0
  311. package/src/lib/server/company-children.js +42 -0
  312. package/src/lib/server/company-children.js.map +1 -0
  313. package/src/lib/server/company-delete.d.ts +18 -0
  314. package/src/lib/server/company-delete.js +44 -21
  315. package/src/lib/server/company-delete.js.map +1 -1
  316. package/src/lib/server/contact-email-history.js +21 -19
  317. package/src/lib/server/contact-email-history.js.map +1 -1
  318. package/src/lib/server/contact-remove.js +27 -2
  319. package/src/lib/server/contact-remove.js.map +1 -1
  320. package/src/lib/server/contact-reports-to.d.ts +61 -0
  321. package/src/lib/server/contact-reports-to.js +114 -0
  322. package/src/lib/server/contact-reports-to.js.map +1 -0
  323. package/src/lib/server/contact-update.d.ts +42 -1
  324. package/src/lib/server/contact-update.js +204 -23
  325. package/src/lib/server/contact-update.js.map +1 -1
  326. package/src/lib/server/convert-host-lead.d.ts +46 -1
  327. package/src/lib/server/convert-host-lead.js +173 -15
  328. package/src/lib/server/convert-host-lead.js.map +1 -1
  329. package/src/lib/server/convert-open-lead.js +12 -5
  330. package/src/lib/server/convert-open-lead.js.map +1 -1
  331. package/src/lib/server/crm-email-activity.d.ts +118 -0
  332. package/src/lib/server/crm-email-activity.js +148 -0
  333. package/src/lib/server/crm-email-activity.js.map +1 -0
  334. package/src/lib/server/crm-inbound-email.js +1 -1
  335. package/src/lib/server/crm-inbound-email.js.map +1 -1
  336. package/src/lib/server/crm-next-activity.d.ts +74 -0
  337. package/src/lib/server/crm-next-activity.js +194 -0
  338. package/src/lib/server/crm-next-activity.js.map +1 -0
  339. package/src/lib/server/crm-record-indexes.d.ts +45 -0
  340. package/src/lib/server/crm-record-indexes.js +78 -0
  341. package/src/lib/server/crm-record-indexes.js.map +1 -0
  342. package/src/lib/server/crm-sharing.d.ts +9 -1
  343. package/src/lib/server/crm-sharing.js +23 -3
  344. package/src/lib/server/crm-sharing.js.map +1 -1
  345. package/src/lib/server/deal-contact-roles.d.ts +27 -0
  346. package/src/lib/server/deal-contact-roles.js +89 -0
  347. package/src/lib/server/deal-contact-roles.js.map +1 -0
  348. package/src/lib/server/email-send.js +2 -1
  349. package/src/lib/server/email-send.js.map +1 -1
  350. package/src/lib/server/lead-convert.d.ts +5 -0
  351. package/src/lib/server/lead-convert.js +19 -3
  352. package/src/lib/server/lead-convert.js.map +1 -1
  353. package/src/lib/server/lead-create.d.ts +17 -2
  354. package/src/lib/server/lead-create.js +46 -14
  355. package/src/lib/server/lead-create.js.map +1 -1
  356. package/src/lib/server/lead-nurturing.d.ts +6 -0
  357. package/src/lib/server/lead-nurturing.js +57 -20
  358. package/src/lib/server/lead-nurturing.js.map +1 -1
  359. package/src/lib/server/lead-picklists.d.ts +35 -0
  360. package/src/lib/server/lead-picklists.js +52 -0
  361. package/src/lib/server/lead-picklists.js.map +1 -0
  362. package/src/lib/server/lead-source-picklist.d.ts +1 -13
  363. package/src/lib/server/lead-source-picklist.js +6 -33
  364. package/src/lib/server/lead-source-picklist.js.map +1 -1
  365. package/src/lib/server/merge-contacts.js +23 -5
  366. package/src/lib/server/merge-contacts.js.map +1 -1
  367. package/src/lib/server/next-activity-routes.js +2 -1
  368. package/src/lib/server/next-activity-routes.js.map +1 -1
  369. package/src/lib/server/person-eraser.d.ts +53 -0
  370. package/src/lib/server/person-eraser.js +149 -0
  371. package/src/lib/server/person-eraser.js.map +1 -0
  372. package/src/lib/server/person-records.d.ts +69 -0
  373. package/src/lib/server/person-records.js +317 -0
  374. package/src/lib/server/person-records.js.map +1 -0
  375. package/src/lib/server/person-refund.d.ts +97 -0
  376. package/src/lib/server/person-refund.js +221 -0
  377. package/src/lib/server/person-refund.js.map +1 -0
  378. package/src/lib/server/picklist-values.d.ts +21 -0
  379. package/src/lib/server/picklist-values.js +308 -0
  380. package/src/lib/server/picklist-values.js.map +1 -0
  381. package/src/lib/server/read-picklist.d.ts +44 -0
  382. package/src/lib/server/read-picklist.js +65 -0
  383. package/src/lib/server/read-picklist.js.map +1 -0
  384. package/src/lib/server/recipe-routes.js +22 -8
  385. package/src/lib/server/recipe-routes.js.map +1 -1
  386. package/src/lib/server/record-email-state.js +7 -1
  387. package/src/lib/server/record-email-state.js.map +1 -1
  388. package/src/lib/server/record-facts.d.ts +3 -0
  389. package/src/lib/server/record-facts.js +233 -31
  390. package/src/lib/server/record-facts.js.map +1 -1
  391. package/src/lib/server/record-origin.d.ts +27 -0
  392. package/src/lib/server/record-origin.js +104 -0
  393. package/src/lib/server/record-origin.js.map +1 -0
  394. package/src/lib/server/record-timeline.js +40 -3
  395. package/src/lib/server/record-timeline.js.map +1 -1
  396. package/src/lib/server/suite-gate.js +4 -3
  397. package/src/lib/server/suite-gate.js.map +1 -1
  398. package/src/lib/server/task-reminders-route.js +2 -1
  399. package/src/lib/server/task-reminders-route.js.map +1 -1
  400. package/src/lib/server/task-routes.js +33 -17
  401. package/src/lib/server/task-routes.js.map +1 -1
  402. package/src/lib/server-deal-stage.d.ts +5 -1
  403. package/src/lib/server-deal-stage.js +10 -5
  404. package/src/lib/server-deal-stage.js.map +1 -1
  405. package/src/lib/server.d.ts +8 -3
  406. package/src/lib/server.js +47 -43
  407. package/src/lib/server.js.map +1 -1
  408. package/src/lib/testing/memory-firestore.d.ts +55 -0
  409. package/src/lib/testing/memory-firestore.js +335 -0
  410. package/src/lib/testing/memory-firestore.js.map +1 -0
  411. package/src/lib/testing/stand-in-email-send-index.d.ts +25 -0
  412. package/src/lib/testing/stand-in-email-send-index.js +49 -0
  413. package/src/lib/testing/stand-in-email-send-index.js.map +1 -0
  414. package/src/lib/transfer/activities.d.ts +30 -0
  415. package/src/lib/transfer/activities.js +132 -0
  416. package/src/lib/transfer/activities.js.map +1 -0
  417. package/src/lib/transfer/aliases.d.ts +22 -0
  418. package/src/lib/transfer/aliases.js +1342 -0
  419. package/src/lib/transfer/aliases.js.map +1 -0
  420. package/src/lib/transfer/common.d.ts +222 -0
  421. package/src/lib/transfer/common.js +832 -0
  422. package/src/lib/transfer/common.js.map +1 -0
  423. package/src/lib/transfer/companies.d.ts +43 -0
  424. package/src/lib/transfer/companies.js +549 -0
  425. package/src/lib/transfer/companies.js.map +1 -0
  426. package/src/lib/transfer/contacts.d.ts +31 -0
  427. package/src/lib/transfer/contacts.js +727 -0
  428. package/src/lib/transfer/contacts.js.map +1 -0
  429. package/src/lib/transfer/deals.d.ts +66 -0
  430. package/src/lib/transfer/deals.js +698 -0
  431. package/src/lib/transfer/deals.js.map +1 -0
  432. package/src/lib/transfer/email-templates-package.d.ts +40 -0
  433. package/src/lib/transfer/email-templates-package.js +76 -0
  434. package/src/lib/transfer/email-templates-package.js.map +1 -0
  435. package/src/lib/transfer/email-templates-package.server.d.ts +32 -0
  436. package/src/lib/transfer/email-templates-package.server.js +176 -0
  437. package/src/lib/transfer/email-templates-package.server.js.map +1 -0
  438. package/src/lib/transfer/fields.d.ts +102 -0
  439. package/src/lib/transfer/fields.js +1755 -0
  440. package/src/lib/transfer/fields.js.map +1 -0
  441. package/src/lib/transfer/leads.d.ts +30 -0
  442. package/src/lib/transfer/leads.js +582 -0
  443. package/src/lib/transfer/leads.js.map +1 -0
  444. package/src/lib/transfer/pipelines.d.ts +21 -0
  445. package/src/lib/transfer/pipelines.js +172 -0
  446. package/src/lib/transfer/pipelines.js.map +1 -0
  447. package/src/lib/transfer/register.d.ts +47 -0
  448. package/src/lib/transfer/register.js +277 -0
  449. package/src/lib/transfer/register.js.map +1 -0
  450. package/src/lib/transfer/tasks.d.ts +30 -0
  451. package/src/lib/transfer/tasks.js +418 -0
  452. package/src/lib/transfer/tasks.js.map +1 -0
  453. package/src/lib/transfer/ui.d.ts +20 -0
  454. package/src/lib/transfer/ui.js +42 -0
  455. package/src/lib/transfer/ui.js.map +1 -0
  456. package/src/lib/components/company-import-drawer.d.ts +0 -42
  457. package/src/lib/components/company-import-drawer.js +0 -99
  458. package/src/lib/components/company-import-drawer.js.map +0 -1
  459. package/src/lib/components/contact-import-drawer.d.ts +0 -46
  460. package/src/lib/components/contact-import-drawer.js +0 -149
  461. package/src/lib/components/contact-import-drawer.js.map +0 -1
  462. package/src/lib/components/crm-export-all-button.d.ts +0 -39
  463. package/src/lib/components/crm-export-all-button.js +0 -98
  464. package/src/lib/components/crm-export-all-button.js.map +0 -1
  465. package/src/lib/components/csv-import-drawer.d.ts +0 -139
  466. package/src/lib/components/csv-import-drawer.js +0 -757
  467. package/src/lib/components/csv-import-drawer.js.map +0 -1
  468. package/src/lib/components/deal-import-drawer.d.ts +0 -24
  469. package/src/lib/components/deal-import-drawer.js +0 -83
  470. package/src/lib/components/deal-import-drawer.js.map +0 -1
  471. package/src/lib/components/lead-import-drawer.d.ts +0 -27
  472. package/src/lib/components/lead-import-drawer.js +0 -118
  473. package/src/lib/components/lead-import-drawer.js.map +0 -1
  474. package/src/lib/components/lead-source-values-card.d.ts +0 -27
  475. package/src/lib/components/lead-source-values-card.js.map +0 -1
  476. package/src/lib/components/task-import-drawer.d.ts +0 -24
  477. package/src/lib/components/task-import-drawer.js +0 -82
  478. package/src/lib/components/task-import-drawer.js.map +0 -1
  479. package/src/lib/model/companies-csv.d.ts +0 -36
  480. package/src/lib/model/companies-csv.js +0 -38
  481. package/src/lib/model/companies-csv.js.map +0 -1
  482. package/src/lib/model/contacts-csv.d.ts +0 -54
  483. package/src/lib/model/contacts-csv.js +0 -67
  484. package/src/lib/model/contacts-csv.js.map +0 -1
  485. package/src/lib/model/crm-company-import.d.ts +0 -154
  486. package/src/lib/model/crm-company-import.js +0 -331
  487. package/src/lib/model/crm-company-import.js.map +0 -1
  488. package/src/lib/model/crm-csv.d.ts +0 -239
  489. package/src/lib/model/crm-csv.js +0 -467
  490. package/src/lib/model/crm-csv.js.map +0 -1
  491. package/src/lib/model/crm-deal-import.d.ts +0 -112
  492. package/src/lib/model/crm-deal-import.js +0 -263
  493. package/src/lib/model/crm-deal-import.js.map +0 -1
  494. package/src/lib/model/crm-import.d.ts +0 -250
  495. package/src/lib/model/crm-import.js +0 -467
  496. package/src/lib/model/crm-import.js.map +0 -1
  497. package/src/lib/model/crm-lead-import.d.ts +0 -138
  498. package/src/lib/model/crm-lead-import.js +0 -446
  499. package/src/lib/model/crm-lead-import.js.map +0 -1
  500. package/src/lib/model/crm-task-import.d.ts +0 -94
  501. package/src/lib/model/crm-task-import.js +0 -275
  502. package/src/lib/model/crm-task-import.js.map +0 -1
  503. package/src/lib/model/deals-csv.d.ts +0 -32
  504. package/src/lib/model/deals-csv.js +0 -36
  505. package/src/lib/model/deals-csv.js.map +0 -1
  506. package/src/lib/model/import-column-shapes.d.ts +0 -36
  507. package/src/lib/model/import-column-shapes.js +0 -76
  508. package/src/lib/model/import-column-shapes.js.map +0 -1
  509. package/src/lib/model/lead-source-values.d.ts +0 -82
  510. package/src/lib/model/lead-source-values.js +0 -149
  511. package/src/lib/model/lead-source-values.js.map +0 -1
  512. package/src/lib/model/leads-csv.d.ts +0 -40
  513. package/src/lib/model/leads-csv.js +0 -40
  514. package/src/lib/model/leads-csv.js.map +0 -1
  515. package/src/lib/model/tasks-csv.d.ts +0 -28
  516. package/src/lib/model/tasks-csv.js +0 -28
  517. package/src/lib/model/tasks-csv.js.map +0 -1
  518. package/src/lib/server/companies-import.d.ts +0 -57
  519. package/src/lib/server/companies-import.js +0 -242
  520. package/src/lib/server/companies-import.js.map +0 -1
  521. package/src/lib/server/contacts-import.d.ts +0 -109
  522. package/src/lib/server/contacts-import.js +0 -393
  523. package/src/lib/server/contacts-import.js.map +0 -1
  524. package/src/lib/server/deals-import.d.ts +0 -76
  525. package/src/lib/server/deals-import.js +0 -248
  526. package/src/lib/server/deals-import.js.map +0 -1
  527. package/src/lib/server/export-route.d.ts +0 -60
  528. package/src/lib/server/export-route.js +0 -447
  529. package/src/lib/server/export-route.js.map +0 -1
  530. package/src/lib/server/import-context.d.ts +0 -87
  531. package/src/lib/server/import-context.js +0 -182
  532. package/src/lib/server/import-context.js.map +0 -1
  533. package/src/lib/server/lead-source-values.d.ts +0 -50
  534. package/src/lib/server/lead-source-values.js +0 -191
  535. package/src/lib/server/lead-source-values.js.map +0 -1
  536. package/src/lib/server/leads-import.d.ts +0 -84
  537. package/src/lib/server/leads-import.js +0 -367
  538. package/src/lib/server/leads-import.js.map +0 -1
  539. package/src/lib/server/tasks-import.d.ts +0 -54
  540. package/src/lib/server/tasks-import.js +0 -160
  541. package/src/lib/server/tasks-import.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../../../libs/plugins/crm/src/lib/components/reports-section.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 type { ConsolePluginPageProps } from '@aglyn/aglyn'\nimport { mdiRefresh } from '@aglyn/shared-data-mdi'\nimport {\n MdiIcon } from '@aglyn/shared-ui-jsx'\nimport { CardColumns } from '@aglyn/shared-ui-jsx/components/card-columns'\nimport {\n Button,\n Stack,\n ToggleButton,\n ToggleButtonGroup,\n Typography,\n} from '@mui/material'\nimport { getCountFromServer, query } from 'firebase/firestore'\nimport { useCallback, useMemo, useState } from 'react'\nimport { useFirestore } from '@aglyn/tenant-feature-instance'\nimport { useCrmScope } from '../hooks/use-crm-scope'\nimport { crmRoutes } from '../model/crm-routes'\nimport { ActivityCard } from './reports/activity-card'\nimport { ClosedDealsCard } from './reports/closed-deals-card'\nimport { ContactsMixCard } from './reports/contacts-mix-card'\nimport { ContactsTrendCard } from './reports/contacts-trend-card'\nimport { ForecastCard } from './reports/forecast-card'\nimport { LeadFunnelCard } from './reports/lead-funnel-card'\nimport { PipelineCard } from './reports/pipeline-card'\nimport { SourceConversionCard } from './reports/source-conversion-card'\nimport { WonLostByOwnerCard } from './reports/won-lost-by-owner-card'\nimport {\n type CrmReportScope,\n reportCacheKey,\n reportCachePrefix,\n scopedCollection,\n visibleToClause,\n} from './reports/report-scope'\nimport { TasksCard } from './reports/tasks-card'\nimport { invalidateAggregateReads, useAggregateRead } from './reports/use-aggregate-read'\nimport {\n CRM_REPORT_PERIOD_LABELS,\n CRM_REPORT_PERIODS,\n type CrmReportPeriod,\n crmReportRange,\n} from '../model/crm-reports'\n\n/**\n * `/crm/reports` — the CRM in aggregate (AGL-2604, AGL-2624).\n *\n * Nine cards, each reading its own collection: contacts over time, contacts\n * by source and stage, which sources convert, this site's lead funnel, the\n * open pipeline, what closed, who logged what, the forecast by close month\n * (AGL-2620, over the pipeline card's own window), and the task load. This\n * section resolves what they share and hands it down — see `CrmReportScope`\n * — so that every card counts the same reader's records over the same\n * clock. The lead funnel is the one card handed the site as well: leads live\n * under the host, not the org.\n *\n * ## The period is a control, and the reads follow it\n *\n * Nothing on this page reads a year on mount. The picker names the period,\n * the period sizes every read (one count per week of it, the deals closed\n * within it), and the default is thirty days. The three cards that are\n * stocks rather than flows — the open pipeline, its forecast, the open\n * tasks — ignore the period because \"what is open\" has no period.\n *\n * ## Scoped like the list\n *\n * Every query carries `visibleTo array-contains-any` over the group's\n * tokens, the predicate the rules evaluate, so a report can never count a\n * record its reader could not open — and the total here is the reader's\n * total, not the org's billable audience, which is the head-count the\n * contacts list keeps for the quota.\n *\n * ## Read once a minute, not once an arrival\n *\n * Every read on this page is keyed by the scope and the period and kept\n * for `AGGREGATE_READ_TTL_MS` — see `useAggregateRead` — so leaving to open\n * a deal the report named and coming straight back costs nothing. Refresh\n * forgets this reader's answers for this org and anchors the period again,\n * which is what makes every card ask afresh.\n */\nexport function ContactsReportsSection(props: ConsolePluginPageProps) {\n const { hostId, org, basePath } = props\n const firestore = useFirestore()\n // The org data root — null until the org lookup settles, and the page\n // reads nothing until it does — and the controller this page is viewed\n // as, resolved the way every CRM surface resolves them so the facet a\n // stage is read from here is the facet the contacts list edits it in.\n const { scope: dataScope, consentGroup, visibleTo } = useCrmScope({ hostId, org })\n // `null` at the organization level (AGL-2630): no clause, and every card\n // totals every site; the holder is then each contact's own.\n const tokens = useMemo(() => (visibleTo ? [...visibleTo] : null), [visibleTo])\n const groupId = consentGroup?.groupId ?? null\n const orgRecord = (org ?? null) as Record<string, unknown> | null\n /*\n * The period AND the moment it was chosen, as one value: the range is\n * anchored when the reader picks, not re-derived from a moving `Date.now()`\n * per render, which would rebuild every query on every pass.\n */\n const [view, setView] = useState<{\n period: CrmReportPeriod\n nowMs: number\n }>(() => ({ period: '30d', nowMs: Date.now() }))\n const range = useMemo(\n () => crmReportRange(view.period, view.nowMs),\n [view],\n )\n const routes = useMemo(() => crmRoutes(basePath ?? ''), [basePath])\n const refresh = useCallback(() => {\n if (dataScope) {\n invalidateAggregateReads(reportCachePrefix({ scope: dataScope, tokens, groupId }))\n }\n // A new anchor is what changes every card's dependencies, so each read\n // runs again and — its key forgotten — reaches the server.\n setView((current) => ({ period: current.period, nowMs: Date.now() }))\n }, [dataScope, tokens, groupId])\n\n const report = useMemo<CrmReportScope | null>(\n () =>\n dataScope\n ? {\n scope: dataScope,\n tokens,\n groupId,\n org: orgRecord,\n period: view.period,\n range,\n nowMs: view.nowMs,\n routes,\n }\n : null,\n [dataScope, tokens, groupId, orgRecord, view, range, routes],\n )\n\n /**\n * Every contact this reader may see, counted once for the two cards that\n * quote it — the tile, and the sample notice that compares the read to it.\n */\n const totalContacts = useAggregateRead<number>(\n () =>\n dataScope\n ? getCountFromServer(\n query(\n scopedCollection(firestore, dataScope, 'contacts'),\n ...visibleToClause(tokens),\n ),\n ).then((snapshot) => snapshot.data().count)\n : null,\n // The anchor is a dependency so Refresh re-asks; the key, which omits\n // it, is what answers a reopened section from memory.\n [firestore, dataScope, tokens, view.nowMs],\n report ? { cacheKey: reportCacheKey(report, 'contacts:total') } : {},\n )\n\n return (\n <Stack spacing={2}>\n <Stack\n direction=\"row\"\n spacing={2}\n sx={{\n alignItems: 'center',\n justifyContent: 'space-between',\n flexWrap: 'wrap',\n }}\n >\n <Typography variant=\"h6\" component=\"h2\">\n {'Reports'}\n </Typography>\n <Stack direction=\"row\" spacing={1} sx={{ alignItems: 'center', flexWrap: 'wrap', rowGap: 1 }}>\n <ToggleButtonGroup\n exclusive\n size=\"small\"\n color=\"primary\"\n value={view.period}\n onChange={(_event, next) => {\n if (next) {\n setView({ period: next as CrmReportPeriod, nowMs: Date.now() })\n }\n }}\n aria-label=\"Report period\"\n >\n {CRM_REPORT_PERIODS.map((period) => (\n <ToggleButton key={period} value={period}>\n {CRM_REPORT_PERIOD_LABELS[period]}\n </ToggleButton>\n ))}\n </ToggleButtonGroup>\n <Button\n size=\"small\"\n startIcon={<MdiIcon path={mdiRefresh.path} size={0.8} />}\n disabled={!report}\n onClick={refresh}\n >\n {'Refresh'}\n </Button>\n </Stack>\n </Stack>\n {report ? (\n <>\n {/*\n The same masonry the billing and staff pages use: columns as tall\n as their own contents, so a short card beside a tall one leaves no\n hole. Measured live before this changed — 271, 272 and 111 pixels\n of dead space down one report, and an odd card stranded with an\n empty column beside it.\n */}\n <CardColumns\n spacing={2}\n items={[\n {\n key: 'trend',\n children: (\n <ContactsTrendCard report={report} totalContacts={totalContacts} />\n ),\n },\n {\n key: 'mix',\n children: (\n <ContactsMixCard report={report} totalContacts={totalContacts} />\n ),\n },\n { key: 'source-conversion', children: <SourceConversionCard report={report} /> },\n { key: 'lead-funnel', children: <LeadFunnelCard report={report} hostId={hostId} /> },\n { key: 'pipeline', children: <PipelineCard report={report} /> },\n {\n key: 'closed',\n /*\n One column item carrying two cards, because multicol picks\n its own break: two consecutive items are only USUALLY\n adjacent, and a card that is a footnote to the one above it\n cannot be left to that. Won and lost by owner asks a second\n question of the very rows Won and lost already read — the\n same window under the same `closed:won` and `closed:lost`\n keys — so it is read as that card's breakdown, and\n `break-inside: avoid` keeps the pair whole in one column.\n */\n children: (\n <Stack spacing={2}>\n <ClosedDealsCard report={report} />\n <WonLostByOwnerCard report={report} />\n </Stack>\n ),\n },\n ]}\n />\n {/*\n Outside the columns: multicol cannot span, and these three read\n across the full width.\n */}\n <Stack spacing={2}>\n <ActivityCard report={report} />\n <ForecastCard report={report} />\n <TasksCard report={report} />\n </Stack>\n </>\n ) : (\n <Typography variant=\"body2\" color=\"text.secondary\">\n {'Loading…'}\n </Typography>\n )}\n </Stack>\n )\n}\nContactsReportsSection.displayName = 'ContactsReportsSection'\n\nexport default ContactsReportsSection\n"],"names":["mdiRefresh","MdiIcon","CardColumns","Button","Stack","ToggleButton","ToggleButtonGroup","Typography","getCountFromServer","query","useCallback","useMemo","useState","useFirestore","useCrmScope","crmRoutes","ActivityCard","ClosedDealsCard","ContactsMixCard","ContactsTrendCard","ForecastCard","LeadFunnelCard","PipelineCard","SourceConversionCard","WonLostByOwnerCard","reportCacheKey","reportCachePrefix","scopedCollection","visibleToClause","TasksCard","invalidateAggregateReads","useAggregateRead","CRM_REPORT_PERIOD_LABELS","CRM_REPORT_PERIODS","crmReportRange","ContactsReportsSection","props","hostId","org","basePath","firestore","scope","dataScope","consentGroup","visibleTo","tokens","groupId","orgRecord","view","setView","period","nowMs","Date","now","range","routes","refresh","current","report","totalContacts","then","snapshot","data","count","cacheKey","spacing","direction","sx","alignItems","justifyContent","flexWrap","variant","component","rowGap","exclusive","size","color","value","onChange","_event","next","aria-label","map","startIcon","path","disabled","onClick","items","key","children","displayName"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../../../../../libs/plugins/crm/src/lib/components/reports-section.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 type { ConsolePluginPageProps } from '@aglyn/aglyn'\nimport { mdiRefresh } from '@aglyn/shared-data-mdi'\nimport {\n MdiIcon } from '@aglyn/shared-ui-jsx'\nimport { CardColumns } from '@aglyn/shared-ui-jsx/components/card-columns'\nimport {\n Button,\n Stack,\n ToggleButton,\n ToggleButtonGroup,\n Typography,\n} from '@mui/material'\nimport { getCountFromServer, query } from 'firebase/firestore'\nimport { useCallback, useMemo, useState } from 'react'\nimport { useFirestore } from '@aglyn/tenant-feature-instance'\nimport { useCrmScope } from '../hooks/use-crm-scope'\nimport { crmRoutes } from '../model/crm-routes'\nimport { ActivityCard } from './reports/activity-card'\nimport { ClosedDealsCard } from './reports/closed-deals-card'\nimport { ContactsMixCard } from './reports/contacts-mix-card'\nimport { ContactsTrendCard } from './reports/contacts-trend-card'\nimport { ForecastCard } from './reports/forecast-card'\nimport { LeadFunnelCard } from './reports/lead-funnel-card'\nimport { LeadSourceCard } from './reports/lead-source-card'\nimport { PipelineCard } from './reports/pipeline-card'\nimport { SourceConversionCard } from './reports/source-conversion-card'\nimport { WonLostByOwnerCard } from './reports/won-lost-by-owner-card'\nimport {\n type CrmReportScope,\n reportCacheKey,\n reportCachePrefix,\n scopedCollection,\n visibleToClause,\n} from './reports/report-scope'\nimport { TasksCard } from './reports/tasks-card'\nimport { invalidateAggregateReads, useAggregateRead } from './reports/use-aggregate-read'\nimport {\n CRM_REPORT_PERIOD_LABELS,\n CRM_REPORT_PERIODS,\n type CrmReportPeriod,\n crmReportRange,\n} from '../model/crm-reports'\n\n/**\n * `/crm/reports` — the CRM in aggregate (AGL-2604, AGL-2624).\n *\n * Nine cards, each reading its own collection: contacts over time, contacts\n * by source and stage, which sources convert, this site's lead funnel, the\n * open pipeline, what closed, who logged what, the forecast by close month\n * (AGL-2620, over the pipeline card's own window), and the task load. This\n * section resolves what they share and hands it down — see `CrmReportScope`\n * — so that every card counts the same reader's records over the same\n * clock. The lead funnel is the one card handed the site as well: leads live\n * under the host, not the org.\n *\n * ## The period is a control, and the reads follow it\n *\n * Nothing on this page reads a year on mount. The picker names the period,\n * the period sizes every read (one count per week of it, the deals closed\n * within it), and the default is thirty days. The three cards that are\n * stocks rather than flows — the open pipeline, its forecast, the open\n * tasks — ignore the period because \"what is open\" has no period.\n *\n * ## Scoped like the list\n *\n * Every query carries `visibleTo array-contains-any` over the group's\n * tokens, the predicate the rules evaluate, so a report can never count a\n * record its reader could not open — and the total here is the reader's\n * total, not the org's billable audience, which is the head-count the\n * contacts list keeps for the quota.\n *\n * ## Read once a minute, not once an arrival\n *\n * Every read on this page is keyed by the scope and the period and kept\n * for `AGGREGATE_READ_TTL_MS` — see `useAggregateRead` — so leaving to open\n * a deal the report named and coming straight back costs nothing. Refresh\n * forgets this reader's answers for this org and anchors the period again,\n * which is what makes every card ask afresh.\n */\nexport function ContactsReportsSection(props: ConsolePluginPageProps) {\n const { hostId, org, basePath } = props\n const firestore = useFirestore()\n // The org data root — null until the org lookup settles, and the page\n // reads nothing until it does — and the controller this page is viewed\n // as, resolved the way every CRM surface resolves them so the facet a\n // stage is read from here is the facet the contacts list edits it in.\n const { scope: dataScope, consentGroup, visibleTo } = useCrmScope({ hostId, org })\n // `null` at the organization level (AGL-2630): no clause, and every card\n // totals every site; the holder is then each contact's own.\n const tokens = useMemo(() => (visibleTo ? [...visibleTo] : null), [visibleTo])\n const groupId = consentGroup?.groupId ?? null\n const orgRecord = (org ?? null) as Record<string, unknown> | null\n /*\n * The period AND the moment it was chosen, as one value: the range is\n * anchored when the reader picks, not re-derived from a moving `Date.now()`\n * per render, which would rebuild every query on every pass.\n */\n const [view, setView] = useState<{\n period: CrmReportPeriod\n nowMs: number\n }>(() => ({ period: '30d', nowMs: Date.now() }))\n const range = useMemo(\n () => crmReportRange(view.period, view.nowMs),\n [view],\n )\n const routes = useMemo(() => crmRoutes(basePath ?? ''), [basePath])\n const refresh = useCallback(() => {\n if (dataScope) {\n invalidateAggregateReads(reportCachePrefix({ scope: dataScope, tokens, groupId }))\n }\n // A new anchor is what changes every card's dependencies, so each read\n // runs again and — its key forgotten — reaches the server.\n setView((current) => ({ period: current.period, nowMs: Date.now() }))\n }, [dataScope, tokens, groupId])\n\n const report = useMemo<CrmReportScope | null>(\n () =>\n dataScope\n ? {\n scope: dataScope,\n tokens,\n groupId,\n org: orgRecord,\n period: view.period,\n range,\n nowMs: view.nowMs,\n routes,\n }\n : null,\n [dataScope, tokens, groupId, orgRecord, view, range, routes],\n )\n\n /**\n * Every contact this reader may see, counted once for the two cards that\n * quote it — the tile, and the sample notice that compares the read to it.\n */\n const totalContacts = useAggregateRead<number>(\n () =>\n dataScope\n ? getCountFromServer(\n query(\n scopedCollection(firestore, dataScope, 'contacts'),\n ...visibleToClause(tokens),\n ),\n ).then((snapshot) => snapshot.data().count)\n : null,\n // The anchor is a dependency so Refresh re-asks; the key, which omits\n // it, is what answers a reopened section from memory.\n [firestore, dataScope, tokens, view.nowMs],\n report ? { cacheKey: reportCacheKey(report, 'contacts:total') } : {},\n )\n\n return (\n <Stack spacing={2}>\n <Stack\n direction=\"row\"\n spacing={2}\n sx={{\n alignItems: 'center',\n justifyContent: 'space-between',\n flexWrap: 'wrap',\n }}\n >\n <Typography variant=\"h6\" component=\"h2\">\n {'Reports'}\n </Typography>\n <Stack direction=\"row\" spacing={1} sx={{ alignItems: 'center', flexWrap: 'wrap', rowGap: 1 }}>\n <ToggleButtonGroup\n exclusive\n size=\"small\"\n color=\"primary\"\n value={view.period}\n onChange={(_event, next) => {\n if (next) {\n setView({ period: next as CrmReportPeriod, nowMs: Date.now() })\n }\n }}\n aria-label=\"Report period\"\n >\n {CRM_REPORT_PERIODS.map((period) => (\n <ToggleButton key={period} value={period}>\n {CRM_REPORT_PERIOD_LABELS[period]}\n </ToggleButton>\n ))}\n </ToggleButtonGroup>\n <Button\n size=\"small\"\n startIcon={<MdiIcon path={mdiRefresh.path} size={0.8} />}\n disabled={!report}\n onClick={refresh}\n >\n {'Refresh'}\n </Button>\n </Stack>\n </Stack>\n {report ? (\n <>\n {/*\n The same masonry the billing and staff pages use: columns as tall\n as their own contents, so a short card beside a tall one leaves no\n hole. Measured live before this changed — 271, 272 and 111 pixels\n of dead space down one report, and an odd card stranded with an\n empty column beside it.\n */}\n <CardColumns\n spacing={2}\n items={[\n {\n key: 'trend',\n children: (\n <ContactsTrendCard report={report} totalContacts={totalContacts} />\n ),\n },\n {\n key: 'mix',\n children: (\n <ContactsMixCard report={report} totalContacts={totalContacts} />\n ),\n },\n { key: 'source-conversion', children: <SourceConversionCard report={report} /> },\n { key: 'lead-funnel', children: <LeadFunnelCard report={report} hostId={hostId} /> },\n { key: 'lead-sources', children: <LeadSourceCard report={report} hostId={hostId} /> },\n { key: 'pipeline', children: <PipelineCard report={report} /> },\n {\n key: 'closed',\n /*\n One column item carrying two cards, because multicol picks\n its own break: two consecutive items are only USUALLY\n adjacent, and a card that is a footnote to the one above it\n cannot be left to that. Won and lost by owner asks a second\n question of the very rows Won and lost already read — the\n same window under the same `closed:won` and `closed:lost`\n keys — so it is read as that card's breakdown, and\n `break-inside: avoid` keeps the pair whole in one column.\n */\n children: (\n <Stack spacing={2}>\n <ClosedDealsCard report={report} />\n <WonLostByOwnerCard report={report} />\n </Stack>\n ),\n },\n ]}\n />\n {/*\n Outside the columns: multicol cannot span, and these three read\n across the full width.\n */}\n <Stack spacing={2}>\n <ActivityCard report={report} />\n <ForecastCard report={report} />\n <TasksCard report={report} />\n </Stack>\n </>\n ) : (\n <Typography variant=\"body2\" color=\"text.secondary\">\n {'Loading…'}\n </Typography>\n )}\n </Stack>\n )\n}\nContactsReportsSection.displayName = 'ContactsReportsSection'\n\nexport default ContactsReportsSection\n"],"names":["mdiRefresh","MdiIcon","CardColumns","Button","Stack","ToggleButton","ToggleButtonGroup","Typography","getCountFromServer","query","useCallback","useMemo","useState","useFirestore","useCrmScope","crmRoutes","ActivityCard","ClosedDealsCard","ContactsMixCard","ContactsTrendCard","ForecastCard","LeadFunnelCard","LeadSourceCard","PipelineCard","SourceConversionCard","WonLostByOwnerCard","reportCacheKey","reportCachePrefix","scopedCollection","visibleToClause","TasksCard","invalidateAggregateReads","useAggregateRead","CRM_REPORT_PERIOD_LABELS","CRM_REPORT_PERIODS","crmReportRange","ContactsReportsSection","props","hostId","org","basePath","firestore","scope","dataScope","consentGroup","visibleTo","tokens","groupId","orgRecord","view","setView","period","nowMs","Date","now","range","routes","refresh","current","report","totalContacts","then","snapshot","data","count","cacheKey","spacing","direction","sx","alignItems","justifyContent","flexWrap","variant","component","rowGap","exclusive","size","color","value","onChange","_event","next","aria-label","map","startIcon","path","disabled","onClick","items","key","children","displayName"],"mappings":"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"}
@@ -1,3 +1,4 @@
1
+ import { type CrmPicklist } from '@aglyn/aglyn';
1
2
  import type { OrgMemberOption } from '../hooks/use-org-member-directory';
2
3
  import { type CrmShareAccess, type CrmSharingCriteria, type CrmSharingObject, type CrmSharingRule, type CrmSharingSite } from '../model/crm-sharing';
3
4
  /** What the drawer hands back: the rule as `crm/sharing` `rule-save` reads it. */
@@ -22,6 +23,10 @@ export interface SharingRuleDrawerProps {
22
23
  value: string;
23
24
  label: string;
24
25
  }[];
26
+ /** The org's Lead source list, which the Lead source criterion picks from. */
27
+ leadSourceList?: CrmPicklist;
28
+ /** The org's Lead status list, whose labels name the statuses a rule matches (AGL-3512). */
29
+ leadStatusList?: CrmPicklist;
25
30
  busy: boolean;
26
31
  onSubmit: (draft: SharingRuleDraft) => void;
27
32
  }
@@ -16,11 +16,12 @@
16
16
  */ 'use client';
17
17
  import { _ as _extends } from "@swc/helpers/_/_extends";
18
18
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
19
- import { CONTACT_LIFECYCLE_STAGE_LABELS, CONTACT_LIFECYCLE_STAGES, CRM_LEAD_STATUS_LABELS, CRM_LEAD_STATUSES, crmMemberPickerLabel } from "@aglyn/aglyn";
19
+ import { CONTACT_LIFECYCLE_STAGE_LABELS, CONTACT_LIFECYCLE_STAGES, CRM_LEAD_SOURCE_PICKLIST, CRM_LEAD_STATUSES, STANDARD_CRM_LEAD_STATUS_PICKLIST, crmLeadStatusLabelFor, crmMemberPickerLabel, crmPicklistDefinition, crmPicklistOptions, groupPicklistOptions } from "@aglyn/aglyn";
20
20
  import { hostIdsFromScope, ORG_SCOPE_TOKEN } from "@aglyn/aglyn/app-utils/scope-tokens";
21
- import { Button, Checkbox, Drawer, FormControl, FormControlLabel, FormGroup, FormHelperText, FormLabel, MenuItem, Radio, RadioGroup, Stack, Switch, TextField, Typography } from "@mui/material";
22
- import { useEffect, useState } from "react";
21
+ import { Button, Checkbox, Drawer, FormControl, FormControlLabel, FormGroup, FormHelperText, FormLabel, ListSubheader, MenuItem, Radio, RadioGroup, Stack, Switch, TextField, Typography } from "@mui/material";
22
+ import { useEffect, useMemo, useState } from "react";
23
23
  import { CRM_SHARING_CRITERIA_FOR, CRM_SHARING_OBJECT_LABELS, CRM_SHARING_OBJECTS } from "../model/crm-sharing.js";
24
+ import { LEAD_SOURCE_DIRECTION_LABELS, LEAD_SOURCE_DIRECTIONS, STANDARD_LEAD_SOURCES } from "../model/lead-source-direction.js";
24
25
  const splitList = (text)=>[
25
26
  ...new Set(text.split(',').map((entry)=>entry.trim()).filter(Boolean))
26
27
  ].slice(0, 20);
@@ -29,12 +30,15 @@ const splitList = (text)=>[
29
30
  * sites that captured them, optional criteria), SHARED WITH (sites, or all
30
31
  * sites), and ACCESS (read-only unless edit is chosen).
31
32
  */ export function SharingRuleDrawer(props) {
33
+ var _props_leadSourceList;
32
34
  const { open, onClose, rule, sites, members, campaigns, busy, onSubmit } = props;
35
+ const leadSourceList = (_props_leadSourceList = props.leadSourceList) != null ? _props_leadSourceList : STANDARD_LEAD_SOURCES;
33
36
  const [name, setName] = useState('');
34
37
  const [object, setObject] = useState('leads');
35
38
  const [enabled, setEnabled] = useState(true);
36
39
  const [sourceHostIds, setSourceHostIds] = useState([]);
37
- const [leadSources, setLeadSources] = useState('');
40
+ const [leadSources, setLeadSources] = useState([]);
41
+ const [leadSourceGroups, setLeadSourceGroups] = useState([]);
38
42
  const [tags, setTags] = useState('');
39
43
  const [stages, setStages] = useState([]);
40
44
  const [ownerUids, setOwnerUids] = useState([]);
@@ -43,38 +47,80 @@ const splitList = (text)=>[
43
47
  const [targets, setTargets] = useState([]);
44
48
  const [access, setAccess] = useState('read');
45
49
  useEffect(()=>{
46
- var _ref, _ref1, _ref2, _ref3, _ref4, _ref5, _ref6, _ref7, _ref8, _ref9;
50
+ var _ref, _ref1, _ref2, _ref3, _ref4, _ref5, _ref6, _ref7, _ref8, _ref9, _ref10;
47
51
  if (!open) return;
48
52
  setName((_ref = rule == null ? void 0 : rule.name) != null ? _ref : '');
49
53
  setObject((_ref1 = rule == null ? void 0 : rule.object) != null ? _ref1 : 'leads');
50
54
  setEnabled((_ref2 = rule == null ? void 0 : rule.enabled) != null ? _ref2 : true);
51
55
  setSourceHostIds((_ref3 = rule == null ? void 0 : rule.sourceHostIds) != null ? _ref3 : []);
52
- setLeadSources(((_ref4 = rule == null ? void 0 : rule.criteria.leadSources) != null ? _ref4 : []).join(', '));
53
- setTags(((_ref5 = rule == null ? void 0 : rule.criteria.tags) != null ? _ref5 : []).join(', '));
54
- setStages((_ref6 = rule == null ? void 0 : rule.criteria.stages) != null ? _ref6 : []);
55
- setOwnerUids((_ref7 = rule == null ? void 0 : rule.criteria.ownerUids) != null ? _ref7 : []);
56
- setCampaignIds((_ref8 = rule == null ? void 0 : rule.criteria.campaignIds) != null ? _ref8 : []);
56
+ setLeadSources((_ref4 = rule == null ? void 0 : rule.criteria.leadSources) != null ? _ref4 : []);
57
+ setLeadSourceGroups((_ref5 = rule == null ? void 0 : rule.criteria.leadSourceGroups) != null ? _ref5 : []);
58
+ setTags(((_ref6 = rule == null ? void 0 : rule.criteria.tags) != null ? _ref6 : []).join(', '));
59
+ setStages((_ref7 = rule == null ? void 0 : rule.criteria.stages) != null ? _ref7 : []);
60
+ setOwnerUids((_ref8 = rule == null ? void 0 : rule.criteria.ownerUids) != null ? _ref8 : []);
61
+ setCampaignIds((_ref9 = rule == null ? void 0 : rule.criteria.campaignIds) != null ? _ref9 : []);
57
62
  setAllSites(rule ? rule.targets.includes(ORG_SCOPE_TOKEN) : true);
58
63
  setTargets(rule ? hostIdsFromScope(rule.targets) : []);
59
- setAccess((_ref9 = rule == null ? void 0 : rule.access) != null ? _ref9 : 'read');
64
+ setAccess((_ref10 = rule == null ? void 0 : rule.access) != null ? _ref10 : 'read');
60
65
  }, [
61
66
  open,
62
67
  rule
63
68
  ]);
64
69
  const offers = CRM_SHARING_CRITERIA_FOR[object];
65
- const stageOptions = object === 'leads' ? CRM_LEAD_STATUSES.map((value)=>({
70
+ const stageOptions = object === 'leads' ? CRM_LEAD_STATUSES.map((value)=>{
71
+ var _props_leadStatusList;
72
+ return {
66
73
  value,
67
- label: CRM_LEAD_STATUS_LABELS[value]
68
- })) : object === 'contacts' ? CONTACT_LIFECYCLE_STAGES.map((value)=>({
74
+ label: crmLeadStatusLabelFor((_props_leadStatusList = props.leadStatusList) != null ? _props_leadStatusList : STANDARD_CRM_LEAD_STATUS_PICKLIST, value)
75
+ };
76
+ }) : object === 'contacts' ? CONTACT_LIFECYCLE_STAGES.map((value)=>({
69
77
  value,
70
78
  label: CONTACT_LIFECYCLE_STAGE_LABELS[value]
71
79
  })) : [];
72
80
  const canSubmit = !busy && name.trim().length > 0 && (allSites || targets.length > 0);
81
+ /*
82
+ * The org's lead source values under their groups (AGL-3511), and every
83
+ * value the rule already names that the list no longer offers, so an
84
+ * edit shows what the rule matches until somebody changes it.
85
+ */ const leadSourceItems = useMemo(()=>{
86
+ var _ref;
87
+ var _crmPicklistDefinition;
88
+ const options = crmPicklistOptions(leadSourceList);
89
+ for (const label of leadSources){
90
+ if (!options.some((option)=>option.label.toLowerCase() === label.toLowerCase())) {
91
+ options.push({
92
+ label,
93
+ inactive: false,
94
+ unlisted: true
95
+ });
96
+ }
97
+ }
98
+ const groups = (_ref = (_crmPicklistDefinition = crmPicklistDefinition(CRM_LEAD_SOURCE_PICKLIST)) == null ? void 0 : _crmPicklistDefinition.groups) != null ? _ref : [];
99
+ return groupPicklistOptions(options, groups).flatMap((section)=>{
100
+ var _ref, _ref1;
101
+ var _section_group, _section_group1;
102
+ return [
103
+ /*#__PURE__*/ _jsx(ListSubheader, {
104
+ children: (_ref = (_section_group = section.group) == null ? void 0 : _section_group.label) != null ? _ref : 'No group'
105
+ }, `group:${(_ref1 = (_section_group1 = section.group) == null ? void 0 : _section_group1.id) != null ? _ref1 : ''}`),
106
+ ...section.options.map((option)=>/*#__PURE__*/ _jsx(MenuItem, {
107
+ value: option.label,
108
+ children: option.unlisted ? `${option.label} (not in the list)` : option.label
109
+ }, option.label))
110
+ ];
111
+ });
112
+ }, [
113
+ leadSourceList,
114
+ leadSources
115
+ ]);
73
116
  const submit = ()=>{
74
117
  if (!canSubmit) return;
75
118
  const criteria = {};
76
- if (offers.includes('leadSources') && splitList(leadSources).length) {
77
- criteria.leadSources = splitList(leadSources);
119
+ if (offers.includes('leadSources') && leadSources.length) {
120
+ criteria.leadSources = leadSources.slice(0, 20);
121
+ }
122
+ if (offers.includes('leadSourceGroups') && leadSourceGroups.length) {
123
+ criteria.leadSourceGroups = leadSourceGroups;
78
124
  }
79
125
  if (offers.includes('tags') && splitList(tags).length) {
80
126
  criteria.tags = splitList(tags).map((tag)=>tag.toLowerCase());
@@ -180,12 +226,55 @@ const splitList = (text)=>[
180
226
  }, site.id))
181
227
  }),
182
228
  offers.includes('leadSources') ? /*#__PURE__*/ _jsx(TextField, {
229
+ select: true,
183
230
  size: "small",
184
231
  label: "Lead source",
185
232
  value: leadSources,
186
- onChange: (event)=>setLeadSources(event.target.value),
187
- helperText: "Any of these, separated by commas. Blank for any source.",
188
- fullWidth: true
233
+ onChange: (event)=>{
234
+ const value = event.target.value;
235
+ setLeadSources(Array.isArray(value) ? value : String(value).split(','));
236
+ },
237
+ slotProps: {
238
+ select: {
239
+ multiple: true,
240
+ displayEmpty: true,
241
+ renderValue: (value)=>value.length ? value.join(', ') : 'Any'
242
+ },
243
+ inputLabel: {
244
+ shrink: true
245
+ }
246
+ },
247
+ fullWidth: true,
248
+ children: leadSourceItems
249
+ }) : null,
250
+ offers.includes('leadSourceGroups') ? /*#__PURE__*/ _jsx(TextField, {
251
+ select: true,
252
+ size: "small",
253
+ label: "Lead source direction",
254
+ value: leadSourceGroups,
255
+ onChange: (event)=>{
256
+ const value = event.target.value;
257
+ setLeadSourceGroups(Array.isArray(value) ? value : String(value).split(','));
258
+ },
259
+ slotProps: {
260
+ select: {
261
+ multiple: true,
262
+ displayEmpty: true,
263
+ renderValue: (value)=>value.length ? value.map((id)=>{
264
+ var _LEAD_SOURCE_DIRECTION_LABELS_id;
265
+ return (_LEAD_SOURCE_DIRECTION_LABELS_id = LEAD_SOURCE_DIRECTION_LABELS[id]) != null ? _LEAD_SOURCE_DIRECTION_LABELS_id : id;
266
+ }).join(', ') : 'Any'
267
+ },
268
+ inputLabel: {
269
+ shrink: true
270
+ }
271
+ },
272
+ helperText: "Matched through each lead source's group on the Fields page, as it stands when the rule runs.",
273
+ fullWidth: true,
274
+ children: LEAD_SOURCE_DIRECTIONS.map((direction)=>/*#__PURE__*/ _jsx(MenuItem, {
275
+ value: direction,
276
+ children: LEAD_SOURCE_DIRECTION_LABELS[direction]
277
+ }, direction))
189
278
  }) : null,
190
279
  offers.includes('tags') ? /*#__PURE__*/ _jsx(TextField, {
191
280
  size: "small",
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../../../libs/plugins/crm/src/lib/components/sharing-rule-drawer.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 CONTACT_LIFECYCLE_STAGE_LABELS,\n CONTACT_LIFECYCLE_STAGES,\n CRM_LEAD_STATUS_LABELS,\n CRM_LEAD_STATUSES,\n crmMemberPickerLabel,\n} from '@aglyn/aglyn'\nimport { hostIdsFromScope, ORG_SCOPE_TOKEN } from '@aglyn/aglyn/app-utils/scope-tokens'\nimport {\n Button,\n Checkbox,\n Drawer,\n FormControl,\n FormControlLabel,\n FormGroup,\n FormHelperText,\n FormLabel,\n MenuItem,\n Radio,\n RadioGroup,\n Stack,\n Switch,\n TextField,\n Typography,\n} from '@mui/material'\nimport { useEffect, useState } from 'react'\nimport type { OrgMemberOption } from '../hooks/use-org-member-directory'\nimport {\n CRM_SHARING_CRITERIA_FOR,\n CRM_SHARING_OBJECT_LABELS,\n CRM_SHARING_OBJECTS,\n type CrmShareAccess,\n type CrmSharingCriteria,\n type CrmSharingObject,\n type CrmSharingRule,\n type CrmSharingSite,\n} from '../model/crm-sharing'\n\n/** What the drawer hands back: the rule as `crm/sharing` `rule-save` reads it. */\nexport interface SharingRuleDraft {\n id?: string\n name: string\n object: CrmSharingObject\n enabled: boolean\n sourceHostIds: string[]\n criteria: CrmSharingCriteria\n targets: 'all' | string[]\n access: CrmShareAccess\n}\n\nexport interface SharingRuleDrawerProps {\n open: boolean\n onClose: () => void\n /** The rule being edited, or `null` for a new one. */\n rule: CrmSharingRule | null\n sites: readonly CrmSharingSite[]\n members: readonly OrgMemberOption[]\n campaigns: readonly { value: string; label: string }[]\n busy: boolean\n onSubmit: (draft: SharingRuleDraft) => void\n}\n\nconst splitList = (text: string) =>\n [...new Set(text.split(',').map((entry) => entry.trim()).filter(Boolean))].slice(0, 20)\n\n/**\n * A sharing rule, three parts (AGL-3336): WHICH RECORDS (an object, the\n * sites that captured them, optional criteria), SHARED WITH (sites, or all\n * sites), and ACCESS (read-only unless edit is chosen).\n */\nexport function SharingRuleDrawer(props: SharingRuleDrawerProps) {\n const { open, onClose, rule, sites, members, campaigns, busy, onSubmit } = props\n const [name, setName] = useState('')\n const [object, setObject] = useState<CrmSharingObject>('leads')\n const [enabled, setEnabled] = useState(true)\n const [sourceHostIds, setSourceHostIds] = useState<string[]>([])\n const [leadSources, setLeadSources] = useState('')\n const [tags, setTags] = useState('')\n const [stages, setStages] = useState<string[]>([])\n const [ownerUids, setOwnerUids] = useState<string[]>([])\n const [campaignIds, setCampaignIds] = useState<string[]>([])\n const [allSites, setAllSites] = useState(true)\n const [targets, setTargets] = useState<string[]>([])\n const [access, setAccess] = useState<CrmShareAccess>('read')\n\n useEffect(() => {\n if (!open) return\n setName(rule?.name ?? '')\n setObject(rule?.object ?? 'leads')\n setEnabled(rule?.enabled ?? true)\n setSourceHostIds(rule?.sourceHostIds ?? [])\n setLeadSources((rule?.criteria.leadSources ?? []).join(', '))\n setTags((rule?.criteria.tags ?? []).join(', '))\n setStages(rule?.criteria.stages ?? [])\n setOwnerUids(rule?.criteria.ownerUids ?? [])\n setCampaignIds(rule?.criteria.campaignIds ?? [])\n setAllSites(rule ? rule.targets.includes(ORG_SCOPE_TOKEN) : true)\n setTargets(rule ? hostIdsFromScope(rule.targets) : [])\n setAccess(rule?.access ?? 'read')\n }, [open, rule])\n\n const offers = CRM_SHARING_CRITERIA_FOR[object]\n const stageOptions: { value: string; label: string }[] =\n object === 'leads'\n ? CRM_LEAD_STATUSES.map((value) => ({ value, label: CRM_LEAD_STATUS_LABELS[value] }))\n : object === 'contacts'\n ? CONTACT_LIFECYCLE_STAGES.map((value) => ({\n value,\n label: CONTACT_LIFECYCLE_STAGE_LABELS[value],\n }))\n : []\n const canSubmit =\n !busy && name.trim().length > 0 && (allSites || targets.length > 0)\n\n const submit = () => {\n if (!canSubmit) return\n const criteria: CrmSharingCriteria = {}\n if (offers.includes('leadSources') && splitList(leadSources).length) {\n criteria.leadSources = splitList(leadSources)\n }\n if (offers.includes('tags') && splitList(tags).length) {\n criteria.tags = splitList(tags).map((tag) => tag.toLowerCase())\n }\n if (stageOptions.length && stages.length) criteria.stages = stages\n if (offers.includes('ownerUids') && ownerUids.length) criteria.ownerUids = ownerUids\n if (offers.includes('campaignIds') && campaignIds.length) criteria.campaignIds = campaignIds\n onSubmit({\n ...(rule ? { id: rule.id } : {}),\n name: name.trim(),\n object,\n enabled,\n sourceHostIds,\n criteria,\n targets: allSites ? 'all' : targets,\n access,\n })\n }\n\n const siteName = (id: string) => sites.find((site) => site.id === id)?.name ?? id\n return (\n <Drawer anchor=\"right\" open={open} onClose={busy ? undefined : onClose}>\n <Stack spacing={2} sx={{ width: 400, maxWidth: '100vw', p: 3 }}>\n <Typography variant=\"h6\">{rule ? 'Edit sharing rule' : 'New sharing rule'}</Typography>\n <Typography variant=\"body2\" color=\"text.secondary\">\n {'Shares every record the rule matches — the ones you already have, and every one ' +\n 'captured or changed from now on. Sharing lets a site see and work a record; it ' +\n 'never shares the person’s consent.'}\n </Typography>\n <TextField\n size=\"small\"\n label=\"Name\"\n value={name}\n onChange={(event) => setName(event.target.value)}\n slotProps={{ htmlInput: { maxLength: 120 } }}\n required\n fullWidth\n />\n <FormLabel>{'Which records'}</FormLabel>\n <TextField\n select\n size=\"small\"\n label=\"Records\"\n value={object}\n onChange={(event) => {\n setObject(event.target.value as CrmSharingObject)\n setStages([])\n }}\n disabled={Boolean(rule)}\n helperText={rule ? 'A rule keeps the kind of record it was made for.' : undefined}\n fullWidth\n >\n {CRM_SHARING_OBJECTS.map((option) => (\n <MenuItem key={option} value={option}>\n {CRM_SHARING_OBJECT_LABELS[option].many}\n </MenuItem>\n ))}\n </TextField>\n <TextField\n select\n size=\"small\"\n label=\"Captured on\"\n value={sourceHostIds}\n onChange={(event) => {\n const value = event.target.value as unknown\n setSourceHostIds(Array.isArray(value) ? (value as string[]) : String(value).split(','))\n }}\n slotProps={{\n select: {\n multiple: true,\n displayEmpty: true,\n renderValue: (value) =>\n (value as string[]).length ? (value as string[]).map(siteName).join(', ') : 'Any site',\n },\n inputLabel: { shrink: true },\n }}\n helperText=\"The sites the record was captured or created on.\"\n fullWidth\n >\n {sites.map((site) => (\n <MenuItem key={site.id} value={site.id}>\n {site.name}\n </MenuItem>\n ))}\n </TextField>\n {offers.includes('leadSources') ? (\n <TextField\n size=\"small\"\n label=\"Lead source\"\n value={leadSources}\n onChange={(event) => setLeadSources(event.target.value)}\n helperText=\"Any of these, separated by commas. Blank for any source.\"\n fullWidth\n />\n ) : null}\n {offers.includes('tags') ? (\n <TextField\n size=\"small\"\n label=\"Tags\"\n value={tags}\n onChange={(event) => setTags(event.target.value)}\n helperText=\"Any of these, separated by commas. Blank for any tags.\"\n fullWidth\n />\n ) : null}\n {stageOptions.length ? (\n <TextField\n select\n size=\"small\"\n label={object === 'leads' ? 'Status' : 'Lifecycle stage'}\n value={stages}\n onChange={(event) => {\n const value = event.target.value as unknown\n setStages(Array.isArray(value) ? (value as string[]) : String(value).split(','))\n }}\n slotProps={{\n select: {\n multiple: true,\n displayEmpty: true,\n renderValue: (value) =>\n (value as string[]).length\n ? (value as string[])\n .map((id) => stageOptions.find((option) => option.value === id)?.label ?? id)\n .join(', ')\n : 'Any',\n },\n inputLabel: { shrink: true },\n }}\n fullWidth\n >\n {stageOptions.map((option) => (\n <MenuItem key={option.value} value={option.value}>\n {option.label}\n </MenuItem>\n ))}\n </TextField>\n ) : null}\n {offers.includes('campaignIds') && campaigns.length ? (\n <TextField\n select\n size=\"small\"\n label=\"Campaign\"\n value={campaignIds}\n onChange={(event) => {\n const value = event.target.value as unknown\n setCampaignIds(Array.isArray(value) ? (value as string[]) : String(value).split(','))\n }}\n slotProps={{\n select: {\n multiple: true,\n displayEmpty: true,\n renderValue: (value) =>\n (value as string[]).length\n ? (value as string[])\n .map((id) => campaigns.find((option) => option.value === id)?.label ?? id)\n .join(', ')\n : 'Any',\n },\n inputLabel: { shrink: true },\n }}\n fullWidth\n >\n {campaigns.map((option) => (\n <MenuItem key={option.value} value={option.value}>\n {option.label}\n </MenuItem>\n ))}\n </TextField>\n ) : null}\n <TextField\n select\n size=\"small\"\n label=\"Owner\"\n value={ownerUids}\n onChange={(event) => {\n const value = event.target.value as unknown\n setOwnerUids(Array.isArray(value) ? (value as string[]) : String(value).split(','))\n }}\n slotProps={{\n select: {\n multiple: true,\n displayEmpty: true,\n renderValue: (value) =>\n (value as string[]).length\n ? (value as string[])\n .map((uid) => {\n const member = members.find((entry) => entry.uid === uid)\n return member ? crmMemberPickerLabel(member) : uid\n })\n .join(', ')\n : 'Anyone',\n },\n inputLabel: { shrink: true },\n }}\n fullWidth\n >\n {members.map((member) => (\n <MenuItem key={member.uid} value={member.uid}>\n {crmMemberPickerLabel(member)}\n </MenuItem>\n ))}\n </TextField>\n <FormControl>\n <FormLabel>{'Shared with'}</FormLabel>\n <FormGroup>\n <FormControlLabel\n control={\n <Checkbox checked={allSites} onChange={(event) => setAllSites(event.target.checked)} />\n }\n label=\"All sites, including sites added later\"\n />\n {sites.map((site) => (\n <FormControlLabel\n key={site.id}\n control={\n <Checkbox\n checked={allSites || targets.includes(site.id)}\n disabled={allSites}\n onChange={(event) =>\n setTargets((current) =>\n event.target.checked\n ? [...current, site.id]\n : current.filter((id) => id !== site.id),\n )\n }\n />\n }\n label={site.name}\n />\n ))}\n </FormGroup>\n </FormControl>\n <FormControl>\n <FormLabel>{'Access'}</FormLabel>\n <RadioGroup\n value={access}\n onChange={(event) => setAccess(event.target.value === 'edit' ? 'edit' : 'read')}\n >\n <FormControlLabel value=\"read\" control={<Radio size=\"small\" />} label=\"Read-only\" />\n <FormControlLabel value=\"edit\" control={<Radio size=\"small\" />} label=\"Read and edit\" />\n </RadioGroup>\n </FormControl>\n <FormControlLabel\n control={<Switch checked={enabled} onChange={(event) => setEnabled(event.target.checked)} />}\n label=\"On\"\n />\n {!enabled ? (\n <FormHelperText>{'Off keeps the rule and takes away what it shared.'}</FormHelperText>\n ) : null}\n <Stack direction=\"row\" spacing={1}>\n <Button variant=\"contained\" disabled={!canSubmit} onClick={submit}>\n {rule ? 'Save rule' : 'Add rule'}\n </Button>\n <Button onClick={onClose} disabled={busy}>\n {'Cancel'}\n </Button>\n </Stack>\n </Stack>\n </Drawer>\n )\n}\nSharingRuleDrawer.displayName = 'SharingRuleDrawer'\n\nexport default SharingRuleDrawer\n"],"names":["CONTACT_LIFECYCLE_STAGE_LABELS","CONTACT_LIFECYCLE_STAGES","CRM_LEAD_STATUS_LABELS","CRM_LEAD_STATUSES","crmMemberPickerLabel","hostIdsFromScope","ORG_SCOPE_TOKEN","Button","Checkbox","Drawer","FormControl","FormControlLabel","FormGroup","FormHelperText","FormLabel","MenuItem","Radio","RadioGroup","Stack","Switch","TextField","Typography","useEffect","useState","CRM_SHARING_CRITERIA_FOR","CRM_SHARING_OBJECT_LABELS","CRM_SHARING_OBJECTS","splitList","text","Set","split","map","entry","trim","filter","Boolean","slice","SharingRuleDrawer","props","open","onClose","rule","sites","members","campaigns","busy","onSubmit","name","setName","object","setObject","enabled","setEnabled","sourceHostIds","setSourceHostIds","leadSources","setLeadSources","tags","setTags","stages","setStages","ownerUids","setOwnerUids","campaignIds","setCampaignIds","allSites","setAllSites","targets","setTargets","access","setAccess","criteria","join","includes","offers","stageOptions","value","label","canSubmit","length","submit","tag","toLowerCase","id","siteName","find","site","anchor","undefined","spacing","sx","width","maxWidth","p","variant","color","size","onChange","event","target","slotProps","htmlInput","maxLength","required","fullWidth","select","disabled","helperText","option","many","Array","isArray","String","multiple","displayEmpty","renderValue","inputLabel","shrink","uid","member","control","checked","current","direction","onClick","displayName"],"mappings":"AAAA;;;;;;;;;;;;;;;CAeC,GACD;;;AAEA,SACEA,8BAA8B,EAC9BC,wBAAwB,EACxBC,sBAAsB,EACtBC,iBAAiB,EACjBC,oBAAoB,QACf,eAAc;AACrB,SAASC,gBAAgB,EAAEC,eAAe,QAAQ,sCAAqC;AACvF,SACEC,MAAM,EACNC,QAAQ,EACRC,MAAM,EACNC,WAAW,EACXC,gBAAgB,EAChBC,SAAS,EACTC,cAAc,EACdC,SAAS,EACTC,QAAQ,EACRC,KAAK,EACLC,UAAU,EACVC,KAAK,EACLC,MAAM,EACNC,SAAS,EACTC,UAAU,QACL,gBAAe;AACtB,SAASC,SAAS,EAAEC,QAAQ,QAAQ,QAAO;AAE3C,SACEC,wBAAwB,EACxBC,yBAAyB,EACzBC,mBAAmB,QAMd,0BAAsB;AA0B7B,MAAMC,YAAY,CAACC,OACjB;WAAI,IAAIC,IAAID,KAAKE,KAAK,CAAC,KAAKC,GAAG,CAAC,CAACC,QAAUA,MAAMC,IAAI,IAAIC,MAAM,CAACC;KAAU,CAACC,KAAK,CAAC,GAAG;AAEtF;;;;CAIC,GACD,OAAO,SAASC,kBAAkBC,KAA6B;IAC7D,MAAM,EAAEC,IAAI,EAAEC,OAAO,EAAEC,IAAI,EAAEC,KAAK,EAAEC,OAAO,EAAEC,SAAS,EAAEC,IAAI,EAAEC,QAAQ,EAAE,GAAGR;IAC3E,MAAM,CAACS,MAAMC,QAAQ,GAAGzB,SAAS;IACjC,MAAM,CAAC0B,QAAQC,UAAU,GAAG3B,SAA2B;IACvD,MAAM,CAAC4B,SAASC,WAAW,GAAG7B,SAAS;IACvC,MAAM,CAAC8B,eAAeC,iBAAiB,GAAG/B,SAAmB,EAAE;IAC/D,MAAM,CAACgC,aAAaC,eAAe,GAAGjC,SAAS;IAC/C,MAAM,CAACkC,MAAMC,QAAQ,GAAGnC,SAAS;IACjC,MAAM,CAACoC,QAAQC,UAAU,GAAGrC,SAAmB,EAAE;IACjD,MAAM,CAACsC,WAAWC,aAAa,GAAGvC,SAAmB,EAAE;IACvD,MAAM,CAACwC,aAAaC,eAAe,GAAGzC,SAAmB,EAAE;IAC3D,MAAM,CAAC0C,UAAUC,YAAY,GAAG3C,SAAS;IACzC,MAAM,CAAC4C,SAASC,WAAW,GAAG7C,SAAmB,EAAE;IACnD,MAAM,CAAC8C,QAAQC,UAAU,GAAG/C,SAAyB;IAErDD,UAAU;;QACR,IAAI,CAACiB,MAAM;QACXS,gBAAQP,wBAAAA,KAAMM,IAAI,mBAAI;QACtBG,mBAAUT,wBAAAA,KAAMQ,MAAM,oBAAI;QAC1BG,oBAAWX,wBAAAA,KAAMU,OAAO,oBAAI;QAC5BG,0BAAiBb,wBAAAA,KAAMY,aAAa,oBAAI,EAAE;QAC1CG,eAAe,UAACf,wBAAAA,KAAM8B,QAAQ,CAAChB,WAAW,oBAAI,EAAE,EAAEiB,IAAI,CAAC;QACvDd,QAAQ,UAACjB,wBAAAA,KAAM8B,QAAQ,CAACd,IAAI,oBAAI,EAAE,EAAEe,IAAI,CAAC;QACzCZ,mBAAUnB,wBAAAA,KAAM8B,QAAQ,CAACZ,MAAM,oBAAI,EAAE;QACrCG,sBAAarB,wBAAAA,KAAM8B,QAAQ,CAACV,SAAS,oBAAI,EAAE;QAC3CG,wBAAevB,wBAAAA,KAAM8B,QAAQ,CAACR,WAAW,oBAAI,EAAE;QAC/CG,YAAYzB,OAAOA,KAAK0B,OAAO,CAACM,QAAQ,CAACnE,mBAAmB;QAC5D8D,WAAW3B,OAAOpC,iBAAiBoC,KAAK0B,OAAO,IAAI,EAAE;QACrDG,mBAAU7B,wBAAAA,KAAM4B,MAAM,oBAAI;IAC5B,GAAG;QAAC9B;QAAME;KAAK;IAEf,MAAMiC,SAASlD,wBAAwB,CAACyB,OAAO;IAC/C,MAAM0B,eACJ1B,WAAW,UACP9C,kBAAkB4B,GAAG,CAAC,CAAC6C,QAAW,CAAA;YAAEA;YAAOC,OAAO3E,sBAAsB,CAAC0E,MAAM;QAAC,CAAA,KAChF3B,WAAW,aACThD,yBAAyB8B,GAAG,CAAC,CAAC6C,QAAW,CAAA;YACvCA;YACAC,OAAO7E,8BAA8B,CAAC4E,MAAM;QAC9C,CAAA,KACA,EAAE;IACV,MAAME,YACJ,CAACjC,QAAQE,KAAKd,IAAI,GAAG8C,MAAM,GAAG,KAAMd,CAAAA,YAAYE,QAAQY,MAAM,GAAG,CAAA;IAEnE,MAAMC,SAAS;QACb,IAAI,CAACF,WAAW;QAChB,MAAMP,WAA+B,CAAC;QACtC,IAAIG,OAAOD,QAAQ,CAAC,kBAAkB9C,UAAU4B,aAAawB,MAAM,EAAE;YACnER,SAAShB,WAAW,GAAG5B,UAAU4B;QACnC;QACA,IAAImB,OAAOD,QAAQ,CAAC,WAAW9C,UAAU8B,MAAMsB,MAAM,EAAE;YACrDR,SAASd,IAAI,GAAG9B,UAAU8B,MAAM1B,GAAG,CAAC,CAACkD,MAAQA,IAAIC,WAAW;QAC9D;QACA,IAAIP,aAAaI,MAAM,IAAIpB,OAAOoB,MAAM,EAAER,SAASZ,MAAM,GAAGA;QAC5D,IAAIe,OAAOD,QAAQ,CAAC,gBAAgBZ,UAAUkB,MAAM,EAAER,SAASV,SAAS,GAAGA;QAC3E,IAAIa,OAAOD,QAAQ,CAAC,kBAAkBV,YAAYgB,MAAM,EAAER,SAASR,WAAW,GAAGA;QACjFjB,SAAS,aACHL,OAAO;YAAE0C,IAAI1C,KAAK0C,EAAE;QAAC,IAAI,CAAC;YAC9BpC,MAAMA,KAAKd,IAAI;YACfgB;YACAE;YACAE;YACAkB;YACAJ,SAASF,WAAW,QAAQE;YAC5BE;;IAEJ;IAEA,MAAMe,WAAW,CAACD;;YAAezC;wBAAAA,cAAAA,MAAM2C,IAAI,CAAC,CAACC,OAASA,KAAKH,EAAE,KAAKA,wBAAjCzC,YAAsCK,IAAI,mBAAIoC;;IAC/E,qBACE,KAAC1E;QAAO8E,QAAO;QAAQhD,MAAMA;QAAMC,SAASK,OAAO2C,YAAYhD;kBAC7D,cAAA,MAACtB;YAAMuE,SAAS;YAAGC,IAAI;gBAAEC,OAAO;gBAAKC,UAAU;gBAASC,GAAG;YAAE;;8BAC3D,KAACxE;oBAAWyE,SAAQ;8BAAMrD,OAAO,sBAAsB;;8BACvD,KAACpB;oBAAWyE,SAAQ;oBAAQC,OAAM;8BAC/B,qFACC,oFACA;;8BAEJ,KAAC3E;oBACC4E,MAAK;oBACLnB,OAAM;oBACND,OAAO7B;oBACPkD,UAAU,CAACC,QAAUlD,QAAQkD,MAAMC,MAAM,CAACvB,KAAK;oBAC/CwB,WAAW;wBAAEC,WAAW;4BAAEC,WAAW;wBAAI;oBAAE;oBAC3CC,QAAQ;oBACRC,SAAS;;8BAEX,KAAC1F;8BAAW;;8BACZ,KAACM;oBACCqF,MAAM;oBACNT,MAAK;oBACLnB,OAAM;oBACND,OAAO3B;oBACPgD,UAAU,CAACC;wBACThD,UAAUgD,MAAMC,MAAM,CAACvB,KAAK;wBAC5BhB,UAAU,EAAE;oBACd;oBACA8C,UAAUvE,QAAQM;oBAClBkE,YAAYlE,OAAO,qDAAqD+C;oBACxEgB,SAAS;8BAER9E,oBAAoBK,GAAG,CAAC,CAAC6E,uBACxB,KAAC7F;4BAAsB6D,OAAOgC;sCAC3BnF,yBAAyB,CAACmF,OAAO,CAACC,IAAI;2BAD1BD;;8BAKnB,KAACxF;oBACCqF,MAAM;oBACNT,MAAK;oBACLnB,OAAM;oBACND,OAAOvB;oBACP4C,UAAU,CAACC;wBACT,MAAMtB,QAAQsB,MAAMC,MAAM,CAACvB,KAAK;wBAChCtB,iBAAiBwD,MAAMC,OAAO,CAACnC,SAAUA,QAAqBoC,OAAOpC,OAAO9C,KAAK,CAAC;oBACpF;oBACAsE,WAAW;wBACTK,QAAQ;4BACNQ,UAAU;4BACVC,cAAc;4BACdC,aAAa,CAACvC,QACZ,AAACA,MAAmBG,MAAM,GAAG,AAACH,MAAmB7C,GAAG,CAACqD,UAAUZ,IAAI,CAAC,QAAQ;wBAChF;wBACA4C,YAAY;4BAAEC,QAAQ;wBAAK;oBAC7B;oBACAV,YAAW;oBACXH,SAAS;8BAER9D,MAAMX,GAAG,CAAC,CAACuD,qBACV,KAACvE;4BAAuB6D,OAAOU,KAAKH,EAAE;sCACnCG,KAAKvC,IAAI;2BADGuC,KAAKH,EAAE;;gBAKzBT,OAAOD,QAAQ,CAAC,+BACf,KAACrD;oBACC4E,MAAK;oBACLnB,OAAM;oBACND,OAAOrB;oBACP0C,UAAU,CAACC,QAAU1C,eAAe0C,MAAMC,MAAM,CAACvB,KAAK;oBACtD+B,YAAW;oBACXH,SAAS;qBAET;gBACH9B,OAAOD,QAAQ,CAAC,wBACf,KAACrD;oBACC4E,MAAK;oBACLnB,OAAM;oBACND,OAAOnB;oBACPwC,UAAU,CAACC,QAAUxC,QAAQwC,MAAMC,MAAM,CAACvB,KAAK;oBAC/C+B,YAAW;oBACXH,SAAS;qBAET;gBACH7B,aAAaI,MAAM,iBAClB,KAAC3D;oBACCqF,MAAM;oBACNT,MAAK;oBACLnB,OAAO5B,WAAW,UAAU,WAAW;oBACvC2B,OAAOjB;oBACPsC,UAAU,CAACC;wBACT,MAAMtB,QAAQsB,MAAMC,MAAM,CAACvB,KAAK;wBAChChB,UAAUkD,MAAMC,OAAO,CAACnC,SAAUA,QAAqBoC,OAAOpC,OAAO9C,KAAK,CAAC;oBAC7E;oBACAsE,WAAW;wBACTK,QAAQ;4BACNQ,UAAU;4BACVC,cAAc;4BACdC,aAAa,CAACvC,QACZ,AAACA,MAAmBG,MAAM,GACtB,AAACH,MACE7C,GAAG,CAAC,CAACoD;;wCAAOR;oDAAAA,qBAAAA,aAAaU,IAAI,CAAC,CAACuB,SAAWA,OAAOhC,KAAK,KAAKO,wBAA/CR,mBAAoDE,KAAK,mBAAIM;mCACzEX,IAAI,CAAC,QACR;wBACR;wBACA4C,YAAY;4BAAEC,QAAQ;wBAAK;oBAC7B;oBACAb,SAAS;8BAER7B,aAAa5C,GAAG,CAAC,CAAC6E,uBACjB,KAAC7F;4BAA4B6D,OAAOgC,OAAOhC,KAAK;sCAC7CgC,OAAO/B,KAAK;2BADA+B,OAAOhC,KAAK;qBAK7B;gBACHF,OAAOD,QAAQ,CAAC,kBAAkB7B,UAAUmC,MAAM,iBACjD,KAAC3D;oBACCqF,MAAM;oBACNT,MAAK;oBACLnB,OAAM;oBACND,OAAOb;oBACPkC,UAAU,CAACC;wBACT,MAAMtB,QAAQsB,MAAMC,MAAM,CAACvB,KAAK;wBAChCZ,eAAe8C,MAAMC,OAAO,CAACnC,SAAUA,QAAqBoC,OAAOpC,OAAO9C,KAAK,CAAC;oBAClF;oBACAsE,WAAW;wBACTK,QAAQ;4BACNQ,UAAU;4BACVC,cAAc;4BACdC,aAAa,CAACvC,QACZ,AAACA,MAAmBG,MAAM,GACtB,AAACH,MACE7C,GAAG,CAAC,CAACoD;;wCAAOvC;oDAAAA,kBAAAA,UAAUyC,IAAI,CAAC,CAACuB,SAAWA,OAAOhC,KAAK,KAAKO,wBAA5CvC,gBAAiDiC,KAAK,mBAAIM;mCACtEX,IAAI,CAAC,QACR;wBACR;wBACA4C,YAAY;4BAAEC,QAAQ;wBAAK;oBAC7B;oBACAb,SAAS;8BAER5D,UAAUb,GAAG,CAAC,CAAC6E,uBACd,KAAC7F;4BAA4B6D,OAAOgC,OAAOhC,KAAK;sCAC7CgC,OAAO/B,KAAK;2BADA+B,OAAOhC,KAAK;qBAK7B;8BACJ,KAACxD;oBACCqF,MAAM;oBACNT,MAAK;oBACLnB,OAAM;oBACND,OAAOf;oBACPoC,UAAU,CAACC;wBACT,MAAMtB,QAAQsB,MAAMC,MAAM,CAACvB,KAAK;wBAChCd,aAAagD,MAAMC,OAAO,CAACnC,SAAUA,QAAqBoC,OAAOpC,OAAO9C,KAAK,CAAC;oBAChF;oBACAsE,WAAW;wBACTK,QAAQ;4BACNQ,UAAU;4BACVC,cAAc;4BACdC,aAAa,CAACvC,QACZ,AAACA,MAAmBG,MAAM,GACtB,AAACH,MACE7C,GAAG,CAAC,CAACuF;oCACJ,MAAMC,SAAS5E,QAAQ0C,IAAI,CAAC,CAACrD,QAAUA,MAAMsF,GAAG,KAAKA;oCACrD,OAAOC,SAASnH,qBAAqBmH,UAAUD;gCACjD,GACC9C,IAAI,CAAC,QACR;wBACR;wBACA4C,YAAY;4BAAEC,QAAQ;wBAAK;oBAC7B;oBACAb,SAAS;8BAER7D,QAAQZ,GAAG,CAAC,CAACwF,uBACZ,KAACxG;4BAA0B6D,OAAO2C,OAAOD,GAAG;sCACzClH,qBAAqBmH;2BADTA,OAAOD,GAAG;;8BAK7B,MAAC5G;;sCACC,KAACI;sCAAW;;sCACZ,MAACF;;8CACC,KAACD;oCACC6G,uBACE,KAAChH;wCAASiH,SAASxD;wCAAUgC,UAAU,CAACC,QAAUhC,YAAYgC,MAAMC,MAAM,CAACsB,OAAO;;oCAEpF5C,OAAM;;gCAEPnC,MAAMX,GAAG,CAAC,CAACuD,qBACV,KAAC3E;wCAEC6G,uBACE,KAAChH;4CACCiH,SAASxD,YAAYE,QAAQM,QAAQ,CAACa,KAAKH,EAAE;4CAC7CuB,UAAUzC;4CACVgC,UAAU,CAACC,QACT9B,WAAW,CAACsD,UACVxB,MAAMC,MAAM,CAACsB,OAAO,GAChB;2DAAIC;wDAASpC,KAAKH,EAAE;qDAAC,GACrBuC,QAAQxF,MAAM,CAAC,CAACiD,KAAOA,OAAOG,KAAKH,EAAE;;wCAKjDN,OAAOS,KAAKvC,IAAI;uCAdXuC,KAAKH,EAAE;;;;;8BAmBpB,MAACzE;;sCACC,KAACI;sCAAW;;sCACZ,MAACG;4BACC2D,OAAOP;4BACP4B,UAAU,CAACC,QAAU5B,UAAU4B,MAAMC,MAAM,CAACvB,KAAK,KAAK,SAAS,SAAS;;8CAExE,KAACjE;oCAAiBiE,OAAM;oCAAO4C,uBAAS,KAACxG;wCAAMgF,MAAK;;oCAAYnB,OAAM;;8CACtE,KAAClE;oCAAiBiE,OAAM;oCAAO4C,uBAAS,KAACxG;wCAAMgF,MAAK;;oCAAYnB,OAAM;;;;;;8BAG1E,KAAClE;oBACC6G,uBAAS,KAACrG;wBAAOsG,SAAStE;wBAAS8C,UAAU,CAACC,QAAU9C,WAAW8C,MAAMC,MAAM,CAACsB,OAAO;;oBACvF5C,OAAM;;gBAEP,CAAC1B,wBACA,KAACtC;8BAAgB;qBACf;8BACJ,MAACK;oBAAMyG,WAAU;oBAAMlC,SAAS;;sCAC9B,KAAClF;4BAAOuF,SAAQ;4BAAYY,UAAU,CAAC5B;4BAAW8C,SAAS5C;sCACxDvC,OAAO,cAAc;;sCAExB,KAAClC;4BAAOqH,SAASpF;4BAASkE,UAAU7D;sCACjC;;;;;;;AAMb;AACAR,kBAAkBwF,WAAW,GAAG;AAEhC,eAAexF,kBAAiB"}
1
+ {"version":3,"sources":["../../../../../../../libs/plugins/crm/src/lib/components/sharing-rule-drawer.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 CONTACT_LIFECYCLE_STAGE_LABELS,\n CONTACT_LIFECYCLE_STAGES,\n CRM_LEAD_SOURCE_PICKLIST,\n CRM_LEAD_STATUSES,\n type CrmPicklist,\n STANDARD_CRM_LEAD_STATUS_PICKLIST,\n crmLeadStatusLabelFor,\n crmMemberPickerLabel,\n crmPicklistDefinition,\n crmPicklistOptions,\n groupPicklistOptions,\n} from '@aglyn/aglyn'\nimport { hostIdsFromScope, ORG_SCOPE_TOKEN } from '@aglyn/aglyn/app-utils/scope-tokens'\nimport {\n Button,\n Checkbox,\n Drawer,\n FormControl,\n FormControlLabel,\n FormGroup,\n FormHelperText,\n FormLabel,\n ListSubheader,\n MenuItem,\n Radio,\n RadioGroup,\n Stack,\n Switch,\n TextField,\n Typography,\n} from '@mui/material'\nimport { type ReactNode, useEffect, useMemo, useState } from 'react'\nimport type { OrgMemberOption } from '../hooks/use-org-member-directory'\nimport {\n CRM_SHARING_CRITERIA_FOR,\n CRM_SHARING_OBJECT_LABELS,\n CRM_SHARING_OBJECTS,\n type CrmShareAccess,\n type CrmSharingCriteria,\n type CrmSharingObject,\n type CrmSharingRule,\n type CrmSharingSite,\n} from '../model/crm-sharing'\nimport {\n LEAD_SOURCE_DIRECTION_LABELS,\n LEAD_SOURCE_DIRECTIONS,\n STANDARD_LEAD_SOURCES,\n} from '../model/lead-source-direction'\n\n/** What the drawer hands back: the rule as `crm/sharing` `rule-save` reads it. */\nexport interface SharingRuleDraft {\n id?: string\n name: string\n object: CrmSharingObject\n enabled: boolean\n sourceHostIds: string[]\n criteria: CrmSharingCriteria\n targets: 'all' | string[]\n access: CrmShareAccess\n}\n\nexport interface SharingRuleDrawerProps {\n open: boolean\n onClose: () => void\n /** The rule being edited, or `null` for a new one. */\n rule: CrmSharingRule | null\n sites: readonly CrmSharingSite[]\n members: readonly OrgMemberOption[]\n campaigns: readonly { value: string; label: string }[]\n /** The org's Lead source list, which the Lead source criterion picks from. */\n leadSourceList?: CrmPicklist\n /** The org's Lead status list, whose labels name the statuses a rule matches (AGL-3512). */\n leadStatusList?: CrmPicklist\n busy: boolean\n onSubmit: (draft: SharingRuleDraft) => void\n}\n\nconst splitList = (text: string) =>\n [...new Set(text.split(',').map((entry) => entry.trim()).filter(Boolean))].slice(0, 20)\n\n/**\n * A sharing rule, three parts (AGL-3336): WHICH RECORDS (an object, the\n * sites that captured them, optional criteria), SHARED WITH (sites, or all\n * sites), and ACCESS (read-only unless edit is chosen).\n */\nexport function SharingRuleDrawer(props: SharingRuleDrawerProps) {\n const { open, onClose, rule, sites, members, campaigns, busy, onSubmit } = props\n const leadSourceList = props.leadSourceList ?? STANDARD_LEAD_SOURCES\n const [name, setName] = useState('')\n const [object, setObject] = useState<CrmSharingObject>('leads')\n const [enabled, setEnabled] = useState(true)\n const [sourceHostIds, setSourceHostIds] = useState<string[]>([])\n const [leadSources, setLeadSources] = useState<string[]>([])\n const [leadSourceGroups, setLeadSourceGroups] = useState<string[]>([])\n const [tags, setTags] = useState('')\n const [stages, setStages] = useState<string[]>([])\n const [ownerUids, setOwnerUids] = useState<string[]>([])\n const [campaignIds, setCampaignIds] = useState<string[]>([])\n const [allSites, setAllSites] = useState(true)\n const [targets, setTargets] = useState<string[]>([])\n const [access, setAccess] = useState<CrmShareAccess>('read')\n\n useEffect(() => {\n if (!open) return\n setName(rule?.name ?? '')\n setObject(rule?.object ?? 'leads')\n setEnabled(rule?.enabled ?? true)\n setSourceHostIds(rule?.sourceHostIds ?? [])\n setLeadSources(rule?.criteria.leadSources ?? [])\n setLeadSourceGroups(rule?.criteria.leadSourceGroups ?? [])\n setTags((rule?.criteria.tags ?? []).join(', '))\n setStages(rule?.criteria.stages ?? [])\n setOwnerUids(rule?.criteria.ownerUids ?? [])\n setCampaignIds(rule?.criteria.campaignIds ?? [])\n setAllSites(rule ? rule.targets.includes(ORG_SCOPE_TOKEN) : true)\n setTargets(rule ? hostIdsFromScope(rule.targets) : [])\n setAccess(rule?.access ?? 'read')\n }, [open, rule])\n\n const offers = CRM_SHARING_CRITERIA_FOR[object]\n const stageOptions: { value: string; label: string }[] =\n object === 'leads'\n ? // A rule matches the MEANING, named as the org names it.\n CRM_LEAD_STATUSES.map((value) => ({\n value,\n label: crmLeadStatusLabelFor(props.leadStatusList ?? STANDARD_CRM_LEAD_STATUS_PICKLIST, value),\n }))\n : object === 'contacts'\n ? CONTACT_LIFECYCLE_STAGES.map((value) => ({\n value,\n label: CONTACT_LIFECYCLE_STAGE_LABELS[value],\n }))\n : []\n const canSubmit =\n !busy && name.trim().length > 0 && (allSites || targets.length > 0)\n /*\n * The org's lead source values under their groups (AGL-3511), and every\n * value the rule already names that the list no longer offers, so an\n * edit shows what the rule matches until somebody changes it.\n */\n const leadSourceItems = useMemo<ReactNode[]>(() => {\n const options = crmPicklistOptions(leadSourceList)\n for (const label of leadSources) {\n if (!options.some((option) => option.label.toLowerCase() === label.toLowerCase())) {\n options.push({ label, inactive: false, unlisted: true })\n }\n }\n const groups = crmPicklistDefinition(CRM_LEAD_SOURCE_PICKLIST)?.groups ?? []\n return groupPicklistOptions(options, groups).flatMap((section) => [\n <ListSubheader key={`group:${section.group?.id ?? ''}`}>\n {section.group?.label ?? 'No group'}\n </ListSubheader>,\n ...section.options.map((option) => (\n <MenuItem key={option.label} value={option.label}>\n {option.unlisted ? `${option.label} (not in the list)` : option.label}\n </MenuItem>\n )),\n ])\n }, [leadSourceList, leadSources])\n\n const submit = () => {\n if (!canSubmit) return\n const criteria: CrmSharingCriteria = {}\n if (offers.includes('leadSources') && leadSources.length) {\n criteria.leadSources = leadSources.slice(0, 20)\n }\n if (offers.includes('leadSourceGroups') && leadSourceGroups.length) {\n criteria.leadSourceGroups = leadSourceGroups\n }\n if (offers.includes('tags') && splitList(tags).length) {\n criteria.tags = splitList(tags).map((tag) => tag.toLowerCase())\n }\n if (stageOptions.length && stages.length) criteria.stages = stages\n if (offers.includes('ownerUids') && ownerUids.length) criteria.ownerUids = ownerUids\n if (offers.includes('campaignIds') && campaignIds.length) criteria.campaignIds = campaignIds\n onSubmit({\n ...(rule ? { id: rule.id } : {}),\n name: name.trim(),\n object,\n enabled,\n sourceHostIds,\n criteria,\n targets: allSites ? 'all' : targets,\n access,\n })\n }\n\n const siteName = (id: string) => sites.find((site) => site.id === id)?.name ?? id\n return (\n <Drawer anchor=\"right\" open={open} onClose={busy ? undefined : onClose}>\n <Stack spacing={2} sx={{ width: 400, maxWidth: '100vw', p: 3 }}>\n <Typography variant=\"h6\">{rule ? 'Edit sharing rule' : 'New sharing rule'}</Typography>\n <Typography variant=\"body2\" color=\"text.secondary\">\n {'Shares every record the rule matches — the ones you already have, and every one ' +\n 'captured or changed from now on. Sharing lets a site see and work a record; it ' +\n 'never shares the person’s consent.'}\n </Typography>\n <TextField\n size=\"small\"\n label=\"Name\"\n value={name}\n onChange={(event) => setName(event.target.value)}\n slotProps={{ htmlInput: { maxLength: 120 } }}\n required\n fullWidth\n />\n <FormLabel>{'Which records'}</FormLabel>\n <TextField\n select\n size=\"small\"\n label=\"Records\"\n value={object}\n onChange={(event) => {\n setObject(event.target.value as CrmSharingObject)\n setStages([])\n }}\n disabled={Boolean(rule)}\n helperText={rule ? 'A rule keeps the kind of record it was made for.' : undefined}\n fullWidth\n >\n {CRM_SHARING_OBJECTS.map((option) => (\n <MenuItem key={option} value={option}>\n {CRM_SHARING_OBJECT_LABELS[option].many}\n </MenuItem>\n ))}\n </TextField>\n <TextField\n select\n size=\"small\"\n label=\"Captured on\"\n value={sourceHostIds}\n onChange={(event) => {\n const value = event.target.value as unknown\n setSourceHostIds(Array.isArray(value) ? (value as string[]) : String(value).split(','))\n }}\n slotProps={{\n select: {\n multiple: true,\n displayEmpty: true,\n renderValue: (value) =>\n (value as string[]).length ? (value as string[]).map(siteName).join(', ') : 'Any site',\n },\n inputLabel: { shrink: true },\n }}\n helperText=\"The sites the record was captured or created on.\"\n fullWidth\n >\n {sites.map((site) => (\n <MenuItem key={site.id} value={site.id}>\n {site.name}\n </MenuItem>\n ))}\n </TextField>\n {offers.includes('leadSources') ? (\n <TextField\n select\n size=\"small\"\n label=\"Lead source\"\n value={leadSources}\n onChange={(event) => {\n const value = event.target.value as unknown\n setLeadSources(Array.isArray(value) ? (value as string[]) : String(value).split(','))\n }}\n slotProps={{\n select: {\n multiple: true,\n displayEmpty: true,\n renderValue: (value) =>\n (value as string[]).length ? (value as string[]).join(', ') : 'Any',\n },\n inputLabel: { shrink: true },\n }}\n fullWidth\n >\n {leadSourceItems}\n </TextField>\n ) : null}\n {offers.includes('leadSourceGroups') ? (\n <TextField\n select\n size=\"small\"\n label=\"Lead source direction\"\n value={leadSourceGroups}\n onChange={(event) => {\n const value = event.target.value as unknown\n setLeadSourceGroups(Array.isArray(value) ? (value as string[]) : String(value).split(','))\n }}\n slotProps={{\n select: {\n multiple: true,\n displayEmpty: true,\n renderValue: (value) =>\n (value as string[]).length\n ? (value as string[])\n .map(\n (id) =>\n LEAD_SOURCE_DIRECTION_LABELS[id as keyof typeof LEAD_SOURCE_DIRECTION_LABELS] ?? id,\n )\n .join(', ')\n : 'Any',\n },\n inputLabel: { shrink: true },\n }}\n helperText=\"Matched through each lead source's group on the Fields page, as it stands when the rule runs.\"\n fullWidth\n >\n {LEAD_SOURCE_DIRECTIONS.map((direction) => (\n <MenuItem key={direction} value={direction}>\n {LEAD_SOURCE_DIRECTION_LABELS[direction]}\n </MenuItem>\n ))}\n </TextField>\n ) : null}\n {offers.includes('tags') ? (\n <TextField\n size=\"small\"\n label=\"Tags\"\n value={tags}\n onChange={(event) => setTags(event.target.value)}\n helperText=\"Any of these, separated by commas. Blank for any tags.\"\n fullWidth\n />\n ) : null}\n {stageOptions.length ? (\n <TextField\n select\n size=\"small\"\n label={object === 'leads' ? 'Status' : 'Lifecycle stage'}\n value={stages}\n onChange={(event) => {\n const value = event.target.value as unknown\n setStages(Array.isArray(value) ? (value as string[]) : String(value).split(','))\n }}\n slotProps={{\n select: {\n multiple: true,\n displayEmpty: true,\n renderValue: (value) =>\n (value as string[]).length\n ? (value as string[])\n .map((id) => stageOptions.find((option) => option.value === id)?.label ?? id)\n .join(', ')\n : 'Any',\n },\n inputLabel: { shrink: true },\n }}\n fullWidth\n >\n {stageOptions.map((option) => (\n <MenuItem key={option.value} value={option.value}>\n {option.label}\n </MenuItem>\n ))}\n </TextField>\n ) : null}\n {offers.includes('campaignIds') && campaigns.length ? (\n <TextField\n select\n size=\"small\"\n label=\"Campaign\"\n value={campaignIds}\n onChange={(event) => {\n const value = event.target.value as unknown\n setCampaignIds(Array.isArray(value) ? (value as string[]) : String(value).split(','))\n }}\n slotProps={{\n select: {\n multiple: true,\n displayEmpty: true,\n renderValue: (value) =>\n (value as string[]).length\n ? (value as string[])\n .map((id) => campaigns.find((option) => option.value === id)?.label ?? id)\n .join(', ')\n : 'Any',\n },\n inputLabel: { shrink: true },\n }}\n fullWidth\n >\n {campaigns.map((option) => (\n <MenuItem key={option.value} value={option.value}>\n {option.label}\n </MenuItem>\n ))}\n </TextField>\n ) : null}\n <TextField\n select\n size=\"small\"\n label=\"Owner\"\n value={ownerUids}\n onChange={(event) => {\n const value = event.target.value as unknown\n setOwnerUids(Array.isArray(value) ? (value as string[]) : String(value).split(','))\n }}\n slotProps={{\n select: {\n multiple: true,\n displayEmpty: true,\n renderValue: (value) =>\n (value as string[]).length\n ? (value as string[])\n .map((uid) => {\n const member = members.find((entry) => entry.uid === uid)\n return member ? crmMemberPickerLabel(member) : uid\n })\n .join(', ')\n : 'Anyone',\n },\n inputLabel: { shrink: true },\n }}\n fullWidth\n >\n {members.map((member) => (\n <MenuItem key={member.uid} value={member.uid}>\n {crmMemberPickerLabel(member)}\n </MenuItem>\n ))}\n </TextField>\n <FormControl>\n <FormLabel>{'Shared with'}</FormLabel>\n <FormGroup>\n <FormControlLabel\n control={\n <Checkbox checked={allSites} onChange={(event) => setAllSites(event.target.checked)} />\n }\n label=\"All sites, including sites added later\"\n />\n {sites.map((site) => (\n <FormControlLabel\n key={site.id}\n control={\n <Checkbox\n checked={allSites || targets.includes(site.id)}\n disabled={allSites}\n onChange={(event) =>\n setTargets((current) =>\n event.target.checked\n ? [...current, site.id]\n : current.filter((id) => id !== site.id),\n )\n }\n />\n }\n label={site.name}\n />\n ))}\n </FormGroup>\n </FormControl>\n <FormControl>\n <FormLabel>{'Access'}</FormLabel>\n <RadioGroup\n value={access}\n onChange={(event) => setAccess(event.target.value === 'edit' ? 'edit' : 'read')}\n >\n <FormControlLabel value=\"read\" control={<Radio size=\"small\" />} label=\"Read-only\" />\n <FormControlLabel value=\"edit\" control={<Radio size=\"small\" />} label=\"Read and edit\" />\n </RadioGroup>\n </FormControl>\n <FormControlLabel\n control={<Switch checked={enabled} onChange={(event) => setEnabled(event.target.checked)} />}\n label=\"On\"\n />\n {!enabled ? (\n <FormHelperText>{'Off keeps the rule and takes away what it shared.'}</FormHelperText>\n ) : null}\n <Stack direction=\"row\" spacing={1}>\n <Button variant=\"contained\" disabled={!canSubmit} onClick={submit}>\n {rule ? 'Save rule' : 'Add rule'}\n </Button>\n <Button onClick={onClose} disabled={busy}>\n {'Cancel'}\n </Button>\n </Stack>\n </Stack>\n </Drawer>\n )\n}\nSharingRuleDrawer.displayName = 'SharingRuleDrawer'\n\nexport default SharingRuleDrawer\n"],"names":["CONTACT_LIFECYCLE_STAGE_LABELS","CONTACT_LIFECYCLE_STAGES","CRM_LEAD_SOURCE_PICKLIST","CRM_LEAD_STATUSES","STANDARD_CRM_LEAD_STATUS_PICKLIST","crmLeadStatusLabelFor","crmMemberPickerLabel","crmPicklistDefinition","crmPicklistOptions","groupPicklistOptions","hostIdsFromScope","ORG_SCOPE_TOKEN","Button","Checkbox","Drawer","FormControl","FormControlLabel","FormGroup","FormHelperText","FormLabel","ListSubheader","MenuItem","Radio","RadioGroup","Stack","Switch","TextField","Typography","useEffect","useMemo","useState","CRM_SHARING_CRITERIA_FOR","CRM_SHARING_OBJECT_LABELS","CRM_SHARING_OBJECTS","LEAD_SOURCE_DIRECTION_LABELS","LEAD_SOURCE_DIRECTIONS","STANDARD_LEAD_SOURCES","splitList","text","Set","split","map","entry","trim","filter","Boolean","slice","SharingRuleDrawer","props","open","onClose","rule","sites","members","campaigns","busy","onSubmit","leadSourceList","name","setName","object","setObject","enabled","setEnabled","sourceHostIds","setSourceHostIds","leadSources","setLeadSources","leadSourceGroups","setLeadSourceGroups","tags","setTags","stages","setStages","ownerUids","setOwnerUids","campaignIds","setCampaignIds","allSites","setAllSites","targets","setTargets","access","setAccess","criteria","join","includes","offers","stageOptions","value","label","leadStatusList","canSubmit","length","leadSourceItems","options","some","option","toLowerCase","push","inactive","unlisted","groups","flatMap","section","group","id","submit","tag","siteName","find","site","anchor","undefined","spacing","sx","width","maxWidth","p","variant","color","size","onChange","event","target","slotProps","htmlInput","maxLength","required","fullWidth","select","disabled","helperText","many","Array","isArray","String","multiple","displayEmpty","renderValue","inputLabel","shrink","direction","uid","member","control","checked","current","onClick","displayName"],"mappings":"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"}
@@ -15,7 +15,7 @@
15
15
  * limitations under the License.
16
16
  */ 'use client';
17
17
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
18
- import { CONTACT_LIFECYCLE_STAGE_LABELS, CRM_LEAD_STATUS_LABELS, pluginDocsHelp } from "@aglyn/aglyn";
18
+ import { CONTACT_LIFECYCLE_STAGE_LABELS, crmLeadStatusLabelFor, isCrmLeadStatus, pluginDocsHelp } from "@aglyn/aglyn";
19
19
  import { mdiDeleteOutline, mdiPencilOutline, mdiRefresh } from "@aglyn/shared-data-mdi";
20
20
  import { CardDisplay, MdiIcon } from "@aglyn/shared-ui-jsx";
21
21
  import RowActionsMenu from "@aglyn/shared-ui-jsx/components/row-actions-menu.component";
@@ -26,6 +26,8 @@ import { Button, LinearProgress, Stack, TableBody, TableCell, TableHead, TableRo
26
26
  import { useCallback, useState } from "react";
27
27
  import { useCrmCampaigns } from "../hooks/use-crm-campaigns.js";
28
28
  import { useCrmSharingRules, useCrmSharingSites } from "../hooks/use-crm-sharing.js";
29
+ import { useLeadSourcePicklist } from "../hooks/use-lead-source-picklist.js";
30
+ import { useLeadStatusPicklist } from "../hooks/use-lead-status-picklist.js";
29
31
  import { useOrgMemberDirectory } from "../hooks/use-org-member-directory.js";
30
32
  import { CRM_SHARING_RULES_MAX, describeShareTargets, describeSharingRuleScope } from "../model/crm-sharing.js";
31
33
  import { callCrmSharing } from "../model/crm-sharing-api.js";
@@ -69,6 +71,10 @@ import { SharingRuleDrawer } from "./sharing-rule-drawer.js";
69
71
  }, {
70
72
  enabled: canManage
71
73
  });
74
+ // The values the Lead source criterion picks from, under their groups (AGL-3511).
75
+ const leadSources = useLeadSourcePicklist(canManage ? orgId : null);
76
+ // The org's names for the lead statuses a rule matches (AGL-3512).
77
+ const leadStatuses = useLeadStatusPicklist(orgId);
72
78
  const [editing, setEditing] = useState(null);
73
79
  const [drawerOpen, setDrawerOpen] = useState(false);
74
80
  const [busy, setBusy] = useState(false);
@@ -113,8 +119,8 @@ import { SharingRuleDrawer } from "./sharing-rule-drawer.js";
113
119
  }, draft.id ? 'Rule saved' : 'Rule added');
114
120
  const canEdit = ready && canManage && !busy;
115
121
  const stageLabel = (id)=>{
116
- var _ref, _CRM_LEAD_STATUS_LABELS_id;
117
- return (_ref = (_CRM_LEAD_STATUS_LABELS_id = CRM_LEAD_STATUS_LABELS[id]) != null ? _CRM_LEAD_STATUS_LABELS_id : CONTACT_LIFECYCLE_STAGE_LABELS[id]) != null ? _ref : id;
122
+ var _ref, _ref1;
123
+ return (_ref = (_ref1 = isCrmLeadStatus(id) ? crmLeadStatusLabelFor(leadStatuses.picklist, id) : null) != null ? _ref1 : CONTACT_LIFECYCLE_STAGE_LABELS[id]) != null ? _ref : id;
118
124
  };
119
125
  return /*#__PURE__*/ _jsxs(CardDisplay, {
120
126
  header: 'Sharing rules',
@@ -275,6 +281,8 @@ import { SharingRuleDrawer } from "./sharing-rule-drawer.js";
275
281
  sites: sites.sites,
276
282
  members: roster.members,
277
283
  campaigns: campaigns.options,
284
+ leadSourceList: leadSources.picklist,
285
+ leadStatusList: leadStatuses.picklist,
278
286
  busy: busy,
279
287
  onSubmit: save
280
288
  })
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../../../libs/plugins/crm/src/lib/components/sharing-rules-card.tsx"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n'use client'\n\nimport {\n CONTACT_LIFECYCLE_STAGE_LABELS,\n type ContactLifecycleStage,\n CRM_LEAD_STATUS_LABELS,\n type CrmLeadStatus,\n pluginDocsHelp,\n} from '@aglyn/aglyn'\nimport { mdiDeleteOutline, mdiPencilOutline, mdiRefresh } from '@aglyn/shared-data-mdi'\nimport { CardDisplay, MdiIcon } from '@aglyn/shared-ui-jsx'\nimport RowActionsMenu from '@aglyn/shared-ui-jsx/components/row-actions-menu.component'\nimport { ScrollTable } from '@aglyn/shared-ui-jsx/components/scroll-table.component'\nimport { useSnackbar } from '@aglyn/shared-ui-snackstack'\nimport { useUser } from '@aglyn/tenant-feature-instance'\nimport {\n Button,\n LinearProgress,\n Stack,\n TableBody,\n TableCell,\n TableHead,\n TableRow,\n Typography,\n} from '@mui/material'\nimport { useCallback, useState } from 'react'\nimport { useCrmCampaigns } from '../hooks/use-crm-campaigns'\nimport { useCrmSharingRules, useCrmSharingSites } from '../hooks/use-crm-sharing'\nimport type { CrmOrgDoc } from '../hooks/use-crm-scope'\nimport { useOrgMemberDirectory } from '../hooks/use-org-member-directory'\nimport {\n CRM_SHARING_RULES_MAX,\n type CrmSharingAction,\n type CrmSharingRule,\n describeShareTargets,\n describeSharingRuleScope,\n} from '../model/crm-sharing'\nimport { callCrmSharing } from '../model/crm-sharing-api'\nimport { SharingRuleDrawer, type SharingRuleDraft } from './sharing-rule-drawer'\n\nexport interface SharingRulesCardProps {\n orgId: string | null\n org: CrmOrgDoc\n canManage: boolean\n ready: boolean\n}\n\n/** How far a rule's recompute has got, as the table shows it. */\nfunction runLabel(rule: CrmSharingRule): string {\n const run = rule.run\n if (rule.deleting) return 'Removing what it shared…'\n if (!run) return rule.enabled ? 'On' : 'Off'\n if (run.status === 'running') {\n return `${run.mode === 'remove' ? 'Removing' : 'Applying'} — ${run.processed} checked, ${run.changed} changed`\n }\n if (run.status === 'failed') return run.error ?? 'Stopped'\n return `${rule.enabled ? 'On' : 'Off'} — ${run.changed} ${run.changed === 1 ? 'record' : 'records'} changed`\n}\n\n/**\n * SHARING RULES — the organization's automated sharing (AGL-3336).\n *\n * A rule shares every record it matches with other sites: the existing ones\n * through a recompute that runs when the rule is saved, with its progress\n * on the row, and every later capture or change through the record-written\n * seam. The recompute runs in passes; the card keeps asking while the page\n * is open, and a rule whose run stopped offers Resume.\n *\n * Mounted at the organization level only: a rule is a fact about the org,\n * and its targets are the org's sites.\n */\nexport function SharingRulesCard(props: SharingRulesCardProps) {\n const { orgId, org, canManage, ready } = props\n const { data: user } = useUser()\n const { enqueueSnackbar } = useSnackbar()\n const rules = useCrmSharingRules(org)\n const sites = useCrmSharingSites({ hostId: null, orgId, enabled: canManage })\n const roster = useOrgMemberDirectory(orgId)\n const campaigns = useCrmCampaigns({ hostId: null, orgId }, { enabled: canManage })\n const [editing, setEditing] = useState<CrmSharingRule | null>(null)\n const [drawerOpen, setDrawerOpen] = useState(false)\n const [busy, setBusy] = useState(false)\n const scope = orgId ? { orgId } : null\n\n /** One action, then `rule-continue` until the rule's run has nothing left. */\n const run = useCallback(\n async (action: CrmSharingAction, body: Record<string, unknown>, said: string) => {\n if (!scope) return\n setBusy(true)\n try {\n let answer = await callCrmSharing(user, scope, action, body)\n const ruleId = answer.rule?.id ?? String(body['ruleId'] ?? '')\n while (answer.more && ruleId) {\n answer = await callCrmSharing(user, scope, 'rule-continue', { ruleId })\n }\n enqueueSnackbar(said, { variant: 'success', persist: false })\n setDrawerOpen(false)\n } catch (error) {\n enqueueSnackbar((error as Error).message, { variant: 'error', allowDuplicate: true })\n } finally {\n setBusy(false)\n }\n },\n // `scope` is rebuilt from `orgId` every render.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [user, orgId, enqueueSnackbar],\n )\n\n const save = (draft: SharingRuleDraft) =>\n void run('rule-save', { rule: draft }, draft.id ? 'Rule saved' : 'Rule added')\n\n const canEdit = ready && canManage && !busy\n const stageLabel = (id: string) =>\n CRM_LEAD_STATUS_LABELS[id as CrmLeadStatus] ??\n CONTACT_LIFECYCLE_STAGE_LABELS[id as ContactLifecycleStage] ??\n id\n return (\n <CardDisplay\n header={'Sharing rules'}\n help={pluginDocsHelp('crmSharing', { anchor: '#sharing-rules' })}\n contentGutterX\n contentGutterY\n contentBordered=\"all\"\n HeaderProps={{\n action: (\n <Button\n variant=\"contained\"\n disabled={!canEdit || rules.length >= CRM_SHARING_RULES_MAX}\n onClick={() => {\n setEditing(null)\n setDrawerOpen(true)\n }}\n >\n {'Add rule'}\n </Button>\n ),\n }}\n >\n <Stack spacing={2}>\n <Typography variant=\"body2\" color=\"text.secondary\">\n {'Share leads, contacts, companies or deals captured on one site with other sites, ' +\n 'automatically. A rule applies to the records you have now and to every one captured ' +\n 'or changed later. Sharing is visibility only: a site never gains a person’s consent ' +\n 'through it.'}\n </Typography>\n {busy ? <LinearProgress /> : null}\n {rules.length === 0 ? (\n <Typography variant=\"body2\" color=\"text.secondary\">\n {'No sharing rules. Every record is visible only to the sites that captured it.'}\n </Typography>\n ) : (\n <ScrollTable size=\"small\">\n <TableHead>\n <TableRow>\n <TableCell>{'Rule'}</TableCell>\n <TableCell>{'Which records'}</TableCell>\n <TableCell>{'Shared with'}</TableCell>\n <TableCell>{'Status'}</TableCell>\n <TableCell align=\"right\" />\n </TableRow>\n </TableHead>\n <TableBody>\n {rules.map((rule) => (\n <TableRow key={rule.id} hover>\n <TableCell>\n <Typography variant=\"body2\">{rule.name}</Typography>\n </TableCell>\n <TableCell>\n <Typography variant=\"body2\">\n {describeSharingRuleScope(rule, sites.siteName, {\n owner: roster.nameOf,\n stage: stageLabel,\n })}\n </Typography>\n </TableCell>\n <TableCell>\n <Typography variant=\"body2\">\n {`${describeShareTargets(rule.targets, sites.siteName)}, ${\n rule.access === 'edit' ? 'read and edit' : 'read-only'\n }`}\n </Typography>\n </TableCell>\n <TableCell>\n <Typography variant=\"body2\" color=\"text.secondary\">\n {runLabel(rule)}\n </Typography>\n </TableCell>\n <TableCell align=\"right\" sx={{ width: 56 }}>\n <RowActionsMenu\n label={rule.name}\n items={[\n {\n key: 'edit',\n label: 'Edit rule',\n icon: <MdiIcon path={mdiPencilOutline.path} size={0.8} />,\n disabled: !canEdit || rule.deleting === true,\n onClick: () => {\n setEditing(rule)\n setDrawerOpen(true)\n },\n },\n ...(rule.run && rule.run.status !== 'done'\n ? [\n {\n key: 'resume',\n label: 'Resume',\n icon: <MdiIcon path={mdiRefresh.path} size={0.8} />,\n disabled: !canEdit,\n onClick: () =>\n void run('rule-continue', { ruleId: rule.id }, 'Rule applied'),\n },\n ]\n : []),\n {\n key: 'delete',\n label: 'Delete rule',\n icon: <MdiIcon path={mdiDeleteOutline.path} size={0.8} />,\n destructive: true,\n disabled: !canEdit,\n onClick: () =>\n void run('rule-delete', { ruleId: rule.id }, 'Rule deleted'),\n },\n ]}\n />\n </TableCell>\n </TableRow>\n ))}\n </TableBody>\n </ScrollTable>\n )}\n {ready && !canManage ? (\n <Typography variant=\"caption\" color=\"text.secondary\">\n {'Only a workspace owner or admin can change sharing rules.'}\n </Typography>\n ) : null}\n </Stack>\n <SharingRuleDrawer\n open={drawerOpen}\n onClose={() => setDrawerOpen(false)}\n rule={editing}\n sites={sites.sites}\n members={roster.members}\n campaigns={campaigns.options}\n busy={busy}\n onSubmit={save}\n />\n </CardDisplay>\n )\n}\nSharingRulesCard.displayName = 'SharingRulesCard'\n\nexport default SharingRulesCard\n"],"names":["CONTACT_LIFECYCLE_STAGE_LABELS","CRM_LEAD_STATUS_LABELS","pluginDocsHelp","mdiDeleteOutline","mdiPencilOutline","mdiRefresh","CardDisplay","MdiIcon","RowActionsMenu","ScrollTable","useSnackbar","useUser","Button","LinearProgress","Stack","TableBody","TableCell","TableHead","TableRow","Typography","useCallback","useState","useCrmCampaigns","useCrmSharingRules","useCrmSharingSites","useOrgMemberDirectory","CRM_SHARING_RULES_MAX","describeShareTargets","describeSharingRuleScope","callCrmSharing","SharingRuleDrawer","runLabel","rule","run","deleting","enabled","status","mode","processed","changed","error","SharingRulesCard","props","orgId","org","canManage","ready","data","user","enqueueSnackbar","rules","sites","hostId","roster","campaigns","editing","setEditing","drawerOpen","setDrawerOpen","busy","setBusy","scope","action","body","said","answer","ruleId","id","String","more","variant","persist","message","allowDuplicate","save","draft","canEdit","stageLabel","header","help","anchor","contentGutterX","contentGutterY","contentBordered","HeaderProps","disabled","length","onClick","spacing","color","size","align","map","hover","name","siteName","owner","nameOf","stage","targets","access","sx","width","label","items","key","icon","path","destructive","open","onClose","members","options","onSubmit","displayName"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../../../../../libs/plugins/crm/src/lib/components/sharing-rules-card.tsx"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n'use client'\n\nimport {\n CONTACT_LIFECYCLE_STAGE_LABELS,\n type ContactLifecycleStage,\n crmLeadStatusLabelFor,\n isCrmLeadStatus,\n pluginDocsHelp,\n} from '@aglyn/aglyn'\nimport { mdiDeleteOutline, mdiPencilOutline, mdiRefresh } from '@aglyn/shared-data-mdi'\nimport { CardDisplay, MdiIcon } from '@aglyn/shared-ui-jsx'\nimport RowActionsMenu from '@aglyn/shared-ui-jsx/components/row-actions-menu.component'\nimport { ScrollTable } from '@aglyn/shared-ui-jsx/components/scroll-table.component'\nimport { useSnackbar } from '@aglyn/shared-ui-snackstack'\nimport { useUser } from '@aglyn/tenant-feature-instance'\nimport {\n Button,\n LinearProgress,\n Stack,\n TableBody,\n TableCell,\n TableHead,\n TableRow,\n Typography,\n} from '@mui/material'\nimport { useCallback, useState } from 'react'\nimport { useCrmCampaigns } from '../hooks/use-crm-campaigns'\nimport { useCrmSharingRules, useCrmSharingSites } from '../hooks/use-crm-sharing'\nimport { useLeadSourcePicklist } from '../hooks/use-lead-source-picklist'\nimport { useLeadStatusPicklist } from '../hooks/use-lead-status-picklist'\nimport type { CrmOrgDoc } from '../hooks/use-crm-scope'\nimport { useOrgMemberDirectory } from '../hooks/use-org-member-directory'\nimport {\n CRM_SHARING_RULES_MAX,\n type CrmSharingAction,\n type CrmSharingRule,\n describeShareTargets,\n describeSharingRuleScope,\n} from '../model/crm-sharing'\nimport { callCrmSharing } from '../model/crm-sharing-api'\nimport { SharingRuleDrawer, type SharingRuleDraft } from './sharing-rule-drawer'\n\nexport interface SharingRulesCardProps {\n orgId: string | null\n org: CrmOrgDoc\n canManage: boolean\n ready: boolean\n}\n\n/** How far a rule's recompute has got, as the table shows it. */\nfunction runLabel(rule: CrmSharingRule): string {\n const run = rule.run\n if (rule.deleting) return 'Removing what it shared…'\n if (!run) return rule.enabled ? 'On' : 'Off'\n if (run.status === 'running') {\n return `${run.mode === 'remove' ? 'Removing' : 'Applying'} — ${run.processed} checked, ${run.changed} changed`\n }\n if (run.status === 'failed') return run.error ?? 'Stopped'\n return `${rule.enabled ? 'On' : 'Off'} — ${run.changed} ${run.changed === 1 ? 'record' : 'records'} changed`\n}\n\n/**\n * SHARING RULES — the organization's automated sharing (AGL-3336).\n *\n * A rule shares every record it matches with other sites: the existing ones\n * through a recompute that runs when the rule is saved, with its progress\n * on the row, and every later capture or change through the record-written\n * seam. The recompute runs in passes; the card keeps asking while the page\n * is open, and a rule whose run stopped offers Resume.\n *\n * Mounted at the organization level only: a rule is a fact about the org,\n * and its targets are the org's sites.\n */\nexport function SharingRulesCard(props: SharingRulesCardProps) {\n const { orgId, org, canManage, ready } = props\n const { data: user } = useUser()\n const { enqueueSnackbar } = useSnackbar()\n const rules = useCrmSharingRules(org)\n const sites = useCrmSharingSites({ hostId: null, orgId, enabled: canManage })\n const roster = useOrgMemberDirectory(orgId)\n const campaigns = useCrmCampaigns({ hostId: null, orgId }, { enabled: canManage })\n // The values the Lead source criterion picks from, under their groups (AGL-3511).\n const leadSources = useLeadSourcePicklist(canManage ? orgId : null)\n // The org's names for the lead statuses a rule matches (AGL-3512).\n const leadStatuses = useLeadStatusPicklist(orgId)\n const [editing, setEditing] = useState<CrmSharingRule | null>(null)\n const [drawerOpen, setDrawerOpen] = useState(false)\n const [busy, setBusy] = useState(false)\n const scope = orgId ? { orgId } : null\n\n /** One action, then `rule-continue` until the rule's run has nothing left. */\n const run = useCallback(\n async (action: CrmSharingAction, body: Record<string, unknown>, said: string) => {\n if (!scope) return\n setBusy(true)\n try {\n let answer = await callCrmSharing(user, scope, action, body)\n const ruleId = answer.rule?.id ?? String(body['ruleId'] ?? '')\n while (answer.more && ruleId) {\n answer = await callCrmSharing(user, scope, 'rule-continue', { ruleId })\n }\n enqueueSnackbar(said, { variant: 'success', persist: false })\n setDrawerOpen(false)\n } catch (error) {\n enqueueSnackbar((error as Error).message, { variant: 'error', allowDuplicate: true })\n } finally {\n setBusy(false)\n }\n },\n // `scope` is rebuilt from `orgId` every render.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [user, orgId, enqueueSnackbar],\n )\n\n const save = (draft: SharingRuleDraft) =>\n void run('rule-save', { rule: draft }, draft.id ? 'Rule saved' : 'Rule added')\n\n const canEdit = ready && canManage && !busy\n const stageLabel = (id: string) =>\n (isCrmLeadStatus(id) ? crmLeadStatusLabelFor(leadStatuses.picklist, id) : null) ??\n CONTACT_LIFECYCLE_STAGE_LABELS[id as ContactLifecycleStage] ??\n id\n return (\n <CardDisplay\n header={'Sharing rules'}\n help={pluginDocsHelp('crmSharing', { anchor: '#sharing-rules' })}\n contentGutterX\n contentGutterY\n contentBordered=\"all\"\n HeaderProps={{\n action: (\n <Button\n variant=\"contained\"\n disabled={!canEdit || rules.length >= CRM_SHARING_RULES_MAX}\n onClick={() => {\n setEditing(null)\n setDrawerOpen(true)\n }}\n >\n {'Add rule'}\n </Button>\n ),\n }}\n >\n <Stack spacing={2}>\n <Typography variant=\"body2\" color=\"text.secondary\">\n {'Share leads, contacts, companies or deals captured on one site with other sites, ' +\n 'automatically. A rule applies to the records you have now and to every one captured ' +\n 'or changed later. Sharing is visibility only: a site never gains a person’s consent ' +\n 'through it.'}\n </Typography>\n {busy ? <LinearProgress /> : null}\n {rules.length === 0 ? (\n <Typography variant=\"body2\" color=\"text.secondary\">\n {'No sharing rules. Every record is visible only to the sites that captured it.'}\n </Typography>\n ) : (\n <ScrollTable size=\"small\">\n <TableHead>\n <TableRow>\n <TableCell>{'Rule'}</TableCell>\n <TableCell>{'Which records'}</TableCell>\n <TableCell>{'Shared with'}</TableCell>\n <TableCell>{'Status'}</TableCell>\n <TableCell align=\"right\" />\n </TableRow>\n </TableHead>\n <TableBody>\n {rules.map((rule) => (\n <TableRow key={rule.id} hover>\n <TableCell>\n <Typography variant=\"body2\">{rule.name}</Typography>\n </TableCell>\n <TableCell>\n <Typography variant=\"body2\">\n {describeSharingRuleScope(rule, sites.siteName, {\n owner: roster.nameOf,\n stage: stageLabel,\n })}\n </Typography>\n </TableCell>\n <TableCell>\n <Typography variant=\"body2\">\n {`${describeShareTargets(rule.targets, sites.siteName)}, ${\n rule.access === 'edit' ? 'read and edit' : 'read-only'\n }`}\n </Typography>\n </TableCell>\n <TableCell>\n <Typography variant=\"body2\" color=\"text.secondary\">\n {runLabel(rule)}\n </Typography>\n </TableCell>\n <TableCell align=\"right\" sx={{ width: 56 }}>\n <RowActionsMenu\n label={rule.name}\n items={[\n {\n key: 'edit',\n label: 'Edit rule',\n icon: <MdiIcon path={mdiPencilOutline.path} size={0.8} />,\n disabled: !canEdit || rule.deleting === true,\n onClick: () => {\n setEditing(rule)\n setDrawerOpen(true)\n },\n },\n ...(rule.run && rule.run.status !== 'done'\n ? [\n {\n key: 'resume',\n label: 'Resume',\n icon: <MdiIcon path={mdiRefresh.path} size={0.8} />,\n disabled: !canEdit,\n onClick: () =>\n void run('rule-continue', { ruleId: rule.id }, 'Rule applied'),\n },\n ]\n : []),\n {\n key: 'delete',\n label: 'Delete rule',\n icon: <MdiIcon path={mdiDeleteOutline.path} size={0.8} />,\n destructive: true,\n disabled: !canEdit,\n onClick: () =>\n void run('rule-delete', { ruleId: rule.id }, 'Rule deleted'),\n },\n ]}\n />\n </TableCell>\n </TableRow>\n ))}\n </TableBody>\n </ScrollTable>\n )}\n {ready && !canManage ? (\n <Typography variant=\"caption\" color=\"text.secondary\">\n {'Only a workspace owner or admin can change sharing rules.'}\n </Typography>\n ) : null}\n </Stack>\n <SharingRuleDrawer\n open={drawerOpen}\n onClose={() => setDrawerOpen(false)}\n rule={editing}\n sites={sites.sites}\n members={roster.members}\n campaigns={campaigns.options}\n leadSourceList={leadSources.picklist}\n leadStatusList={leadStatuses.picklist}\n busy={busy}\n onSubmit={save}\n />\n </CardDisplay>\n )\n}\nSharingRulesCard.displayName = 'SharingRulesCard'\n\nexport default SharingRulesCard\n"],"names":["CONTACT_LIFECYCLE_STAGE_LABELS","crmLeadStatusLabelFor","isCrmLeadStatus","pluginDocsHelp","mdiDeleteOutline","mdiPencilOutline","mdiRefresh","CardDisplay","MdiIcon","RowActionsMenu","ScrollTable","useSnackbar","useUser","Button","LinearProgress","Stack","TableBody","TableCell","TableHead","TableRow","Typography","useCallback","useState","useCrmCampaigns","useCrmSharingRules","useCrmSharingSites","useLeadSourcePicklist","useLeadStatusPicklist","useOrgMemberDirectory","CRM_SHARING_RULES_MAX","describeShareTargets","describeSharingRuleScope","callCrmSharing","SharingRuleDrawer","runLabel","rule","run","deleting","enabled","status","mode","processed","changed","error","SharingRulesCard","props","orgId","org","canManage","ready","data","user","enqueueSnackbar","rules","sites","hostId","roster","campaigns","leadSources","leadStatuses","editing","setEditing","drawerOpen","setDrawerOpen","busy","setBusy","scope","action","body","said","answer","ruleId","id","String","more","variant","persist","message","allowDuplicate","save","draft","canEdit","stageLabel","picklist","header","help","anchor","contentGutterX","contentGutterY","contentBordered","HeaderProps","disabled","length","onClick","spacing","color","size","align","map","hover","name","siteName","owner","nameOf","stage","targets","access","sx","width","label","items","key","icon","path","destructive","open","onClose","members","options","leadSourceList","leadStatusList","onSubmit","displayName"],"mappings":"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"}
@@ -8,8 +8,14 @@ import type { CrmRecordKind } from '../hooks/use-crm-record-names';
8
8
  */
9
9
  export declare const TASK_KIND_ICONS: Record<CrmTaskKind, string>;
10
10
  export declare const RECORD_KIND_ICONS: Record<CrmRecordKind, string>;
11
+ /**
12
+ * The task's type: the icon of its meaning and the org's label for it
13
+ * (AGL-3517) — `label`, from `crmTaskPicklistLabels`, or the built-in name
14
+ * of the kind where a surface has no list to hand.
15
+ */
11
16
  export declare function TaskKindCell(props: {
12
17
  kind: CrmTaskKind;
18
+ label?: string;
13
19
  iconOnly?: boolean;
14
20
  }): import("react").JSX.Element;
15
21
  export declare namespace TaskKindCell {
@@ -18,10 +24,12 @@ export declare namespace TaskKindCell {
18
24
  /**
19
25
  * Priority as a chip. Only `high` is colored: a column where every row
20
26
  * carries a colored chip is a column nobody scans, and "normal" is the
21
- * absence of a flag rather than a flag of its own.
27
+ * absence of a flag rather than a flag of its own. The color follows the
28
+ * MEANING; the text is the org's label for it when one is passed (AGL-3517).
22
29
  */
23
30
  export declare function TaskPriorityChip(props: {
24
31
  priority: CrmTaskPriority;
32
+ label?: string;
25
33
  }): import("react").JSX.Element;
26
34
  export declare namespace TaskPriorityChip {
27
35
  var displayName: string;