@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,99 +0,0 @@
1
- /**
2
- * @license
3
- * Copyright 2026 Aglyn LLC
4
- *
5
- * Licensed under the Apache License, Version 2.0 (the "License");
6
- * you may not use this file except in compliance with the License.
7
- * You may obtain a copy of the License at
8
- *
9
- * http://www.apache.org/licenses/LICENSE-2.0
10
- *
11
- * Unless required by applicable law or agreed to in writing, software
12
- * distributed under the License is distributed on an "AS IS" BASIS,
13
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
- * See the License for the specific language governing permissions and
15
- * limitations under the License.
16
- */ 'use client';
17
- import { jsx as _jsx } from "react/jsx-runtime";
18
- /**
19
- * IMPORTING A COMPANIES FILE — the company vocabulary over the shared
20
- * drawer (AGL-2621).
21
- *
22
- * The server half is `server/companies-import.ts`. What is particular to
23
- * companies: the name is the one cell every row needs (a domain is a key,
24
- * a name is the caption the list cannot do without), the custom fields
25
- * are the org's COMPANY definitions (AGL-2661), and a row is matched to a
26
- * company already filed by its domain first and its name second.
27
- */ import { pluginDocsHelp } from "@aglyn/aglyn";
28
- import { COMPANY_IMPORT_CHUNK_SIZE, COMPANY_IMPORT_FIELD_LABELS, COMPANY_IMPORT_FIELDS, COMPANY_IMPORT_MAX_ROWS, COMPANY_IMPORT_PREVIEW_ROWS, COMPANY_IMPORT_SKIP_LABELS, companyImportSkippedCsv, emptyCompanyImportResult, guessCompanyImportMapping, mapCompanyImportRow, mergeCompanyImportResults } from "../model/crm-company-import.js";
29
- import { useMemo } from "react";
30
- import { useContactFieldDefinitions } from "../hooks/use-contact-field-definitions.js";
31
- import { useCrmScope } from "../hooks/use-crm-scope.js";
32
- import { companyImportTemplateCsv } from "../model/companies-csv.js";
33
- import { CsvImportButton, CsvImportDrawer } from "./csv-import-drawer.js";
34
- /** The browser-side address of the route one chunk is posted to. */ export const COMPANIES_IMPORT_URL = '/api/crm/companies-import';
35
- /** The company vocabulary, over the org's company custom fields (AGL-2661). */ export function companyImportVocabulary(fields) {
36
- return {
37
- title: 'Import companies from CSV',
38
- collection: 'companies',
39
- help: pluginDocsHelp('companies', {
40
- anchor: '#import-from-csv'
41
- }),
42
- sitePickerHelperText: 'The site these companies are filed under — it decides which of your ' + 'sites may see them.',
43
- intro: 'A CSV with a header row. Match its columns to company fields below, ' + 'check the preview, then import. A company already in your list — by ' + 'domain, or failing that by name — is updated rather than added twice. ' + `Up to ${COMPANY_IMPORT_MAX_ROWS.toLocaleString()} rows per file — split ` + 'a larger one.',
44
- fields: COMPANY_IMPORT_FIELDS,
45
- fieldLabels: COMPANY_IMPORT_FIELD_LABELS,
46
- customFields: fields,
47
- requiredField: 'name',
48
- requiredWarning: 'Choose which column holds the company name. It is the one field every ' + 'row needs.',
49
- unusableNotice: (count, total)=>`${count.toLocaleString()} of ${total.toLocaleString()} rows have no ` + 'company name and will be skipped. You can download them after the ' + 'import.',
50
- guessMapping: (columns)=>guessCompanyImportMapping(columns, fields),
51
- mapRow: (cells, mapping)=>mapCompanyImportRow(cells, mapping),
52
- route: COMPANIES_IMPORT_URL,
53
- maxRows: COMPANY_IMPORT_MAX_ROWS,
54
- chunkSize: COMPANY_IMPORT_CHUNK_SIZE,
55
- previewRows: COMPANY_IMPORT_PREVIEW_ROWS,
56
- emptyResult: emptyCompanyImportResult,
57
- mergeResults: mergeCompanyImportResults,
58
- skipLabels: COMPANY_IMPORT_SKIP_LABELS,
59
- skippedCsv: companyImportSkippedCsv,
60
- skippedFileName: 'skipped-companies.csv',
61
- templateCsv: companyImportTemplateCsv,
62
- templateFileName: 'companies-template.csv'
63
- };
64
- }
65
- /** The vocabulary with no custom fields — what a surface without an org resolves to. */ export const COMPANY_IMPORT_VOCABULARY = companyImportVocabulary([]);
66
- export function CompanyImportDrawer(props) {
67
- const { open, onClose, hostId, org } = props;
68
- // The org's company fields, read only while the drawer is open.
69
- const { orgId } = useCrmScope({
70
- hostId,
71
- org
72
- });
73
- const { active } = useContactFieldDefinitions(open ? orgId : null, 'company');
74
- const vocabulary = useMemo(()=>companyImportVocabulary(active), [
75
- active
76
- ]);
77
- return /*#__PURE__*/ _jsx(CsvImportDrawer, {
78
- open: open,
79
- onClose: onClose,
80
- hostId: hostId,
81
- vocabulary: vocabulary
82
- });
83
- }
84
- CompanyImportDrawer.displayName = 'CompanyImportDrawer';
85
- /** The "Import CSV" action on the companies list, with the drawer it opens. */ export function CompanyImportButton(props) {
86
- const { hostId, org } = props;
87
- return /*#__PURE__*/ _jsx(CsvImportButton, {
88
- children: (open, onClose)=>/*#__PURE__*/ _jsx(CompanyImportDrawer, {
89
- open: open,
90
- onClose: onClose,
91
- hostId: hostId,
92
- org: org
93
- })
94
- });
95
- }
96
- CompanyImportButton.displayName = 'CompanyImportButton';
97
- export default CompanyImportDrawer;
98
-
99
- //# sourceMappingURL=company-import-drawer.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../../../../../../libs/plugins/crm/src/lib/components/company-import-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\n/**\n * IMPORTING A COMPANIES FILE — the company vocabulary over the shared\n * drawer (AGL-2621).\n *\n * The server half is `server/companies-import.ts`. What is particular to\n * companies: the name is the one cell every row needs (a domain is a key,\n * a name is the caption the list cannot do without), the custom fields\n * are the org's COMPANY definitions (AGL-2661), and a row is matched to a\n * company already filed by its domain first and its name second.\n */\n\nimport {\n type ConsolePluginPageProps,\n type ContactFieldDefinition,\n pluginDocsHelp,\n} from '@aglyn/aglyn'\nimport {\n COMPANY_IMPORT_CHUNK_SIZE,\n COMPANY_IMPORT_FIELD_LABELS,\n COMPANY_IMPORT_FIELDS,\n COMPANY_IMPORT_MAX_ROWS,\n COMPANY_IMPORT_PREVIEW_ROWS,\n COMPANY_IMPORT_SKIP_LABELS,\n type CompanyImportField,\n type CompanyImportRawRow,\n type CompanyImportSkippedRow,\n companyImportSkippedCsv,\n emptyCompanyImportResult,\n guessCompanyImportMapping,\n mapCompanyImportRow,\n mergeCompanyImportResults,\n} from '../model/crm-company-import'\nimport { useMemo } from 'react'\nimport { useContactFieldDefinitions } from '../hooks/use-contact-field-definitions'\nimport { useCrmScope } from '../hooks/use-crm-scope'\nimport { companyImportTemplateCsv } from '../model/companies-csv'\nimport {\n CsvImportButton,\n CsvImportDrawer,\n type CsvImportVocabulary,\n} from './csv-import-drawer'\n\n/** The browser-side address of the route one chunk is posted to. */\nexport const COMPANIES_IMPORT_URL = '/api/crm/companies-import'\n\n/** The company vocabulary, over the org's company custom fields (AGL-2661). */\nexport function companyImportVocabulary(\n fields: readonly ContactFieldDefinition[],\n): CsvImportVocabulary<\n CompanyImportField,\n CompanyImportRawRow & Record<string, unknown>,\n CompanyImportSkippedRow\n> {\n return {\n title: 'Import companies from CSV',\n collection: 'companies',\n help: pluginDocsHelp('companies', { anchor: '#import-from-csv' }),\n sitePickerHelperText:\n 'The site these companies are filed under — it decides which of your ' +\n 'sites may see them.',\n intro:\n 'A CSV with a header row. Match its columns to company fields below, ' +\n 'check the preview, then import. A company already in your list — by ' +\n 'domain, or failing that by name — is updated rather than added twice. ' +\n `Up to ${COMPANY_IMPORT_MAX_ROWS.toLocaleString()} rows per file — split ` +\n 'a larger one.',\n fields: COMPANY_IMPORT_FIELDS,\n fieldLabels: COMPANY_IMPORT_FIELD_LABELS,\n customFields: fields,\n requiredField: 'name',\n requiredWarning:\n 'Choose which column holds the company name. It is the one field every ' +\n 'row needs.',\n unusableNotice: (count, total) =>\n `${count.toLocaleString()} of ${total.toLocaleString()} rows have no ` +\n 'company name and will be skipped. You can download them after the ' +\n 'import.',\n guessMapping: (columns) => guessCompanyImportMapping(columns, fields),\n mapRow: (cells, mapping) =>\n mapCompanyImportRow(cells, mapping) as CompanyImportRawRow & Record<string, unknown>,\n route: COMPANIES_IMPORT_URL,\n maxRows: COMPANY_IMPORT_MAX_ROWS,\n chunkSize: COMPANY_IMPORT_CHUNK_SIZE,\n previewRows: COMPANY_IMPORT_PREVIEW_ROWS,\n emptyResult: emptyCompanyImportResult,\n mergeResults: mergeCompanyImportResults,\n skipLabels: COMPANY_IMPORT_SKIP_LABELS,\n skippedCsv: companyImportSkippedCsv,\n skippedFileName: 'skipped-companies.csv',\n templateCsv: companyImportTemplateCsv,\n templateFileName: 'companies-template.csv',\n }\n}\n\n/** The vocabulary with no custom fields — what a surface without an org resolves to. */\nexport const COMPANY_IMPORT_VOCABULARY = companyImportVocabulary([])\n\nexport interface CompanyImportDrawerProps {\n open: boolean\n onClose: () => void\n /** The site the file is filed under, or `null` at the organization level (AGL-2630). */\n hostId: string | null\n /** The org, for the company field definitions the mapping offers (AGL-2661). */\n org?: ConsolePluginPageProps['org']\n}\n\nexport function CompanyImportDrawer(props: CompanyImportDrawerProps) {\n const { open, onClose, hostId, org } = props\n // The org's company fields, read only while the drawer is open.\n const { orgId } = useCrmScope({ hostId, org })\n const { active } = useContactFieldDefinitions(open ? orgId : null, 'company')\n const vocabulary = useMemo(() => companyImportVocabulary(active), [active])\n return (\n <CsvImportDrawer\n open={open}\n onClose={onClose}\n hostId={hostId}\n vocabulary={vocabulary}\n />\n )\n}\nCompanyImportDrawer.displayName = 'CompanyImportDrawer'\n\n/** The \"Import CSV\" action on the companies list, with the drawer it opens. */\nexport function CompanyImportButton(props: {\n hostId: string | null\n org?: ConsolePluginPageProps['org']\n}) {\n const { hostId, org } = props\n return (\n <CsvImportButton>\n {(open, onClose) => (\n <CompanyImportDrawer open={open} onClose={onClose} hostId={hostId} org={org} />\n )}\n </CsvImportButton>\n )\n}\nCompanyImportButton.displayName = 'CompanyImportButton'\n\nexport default CompanyImportDrawer\n"],"names":["pluginDocsHelp","COMPANY_IMPORT_CHUNK_SIZE","COMPANY_IMPORT_FIELD_LABELS","COMPANY_IMPORT_FIELDS","COMPANY_IMPORT_MAX_ROWS","COMPANY_IMPORT_PREVIEW_ROWS","COMPANY_IMPORT_SKIP_LABELS","companyImportSkippedCsv","emptyCompanyImportResult","guessCompanyImportMapping","mapCompanyImportRow","mergeCompanyImportResults","useMemo","useContactFieldDefinitions","useCrmScope","companyImportTemplateCsv","CsvImportButton","CsvImportDrawer","COMPANIES_IMPORT_URL","companyImportVocabulary","fields","title","collection","help","anchor","sitePickerHelperText","intro","toLocaleString","fieldLabels","customFields","requiredField","requiredWarning","unusableNotice","count","total","guessMapping","columns","mapRow","cells","mapping","route","maxRows","chunkSize","previewRows","emptyResult","mergeResults","skipLabels","skippedCsv","skippedFileName","templateCsv","templateFileName","COMPANY_IMPORT_VOCABULARY","CompanyImportDrawer","props","open","onClose","hostId","org","orgId","active","vocabulary","displayName","CompanyImportButton"],"mappings":"AAAA;;;;;;;;;;;;;;;CAeC,GACD;;AAEA;;;;;;;;;CASC,GAED,SAGEA,cAAc,QACT,eAAc;AACrB,SACEC,yBAAyB,EACzBC,2BAA2B,EAC3BC,qBAAqB,EACrBC,uBAAuB,EACvBC,2BAA2B,EAC3BC,0BAA0B,EAI1BC,uBAAuB,EACvBC,wBAAwB,EACxBC,yBAAyB,EACzBC,mBAAmB,EACnBC,yBAAyB,QACpB,iCAA6B;AACpC,SAASC,OAAO,QAAQ,QAAO;AAC/B,SAASC,0BAA0B,QAAQ,4CAAwC;AACnF,SAASC,WAAW,QAAQ,4BAAwB;AACpD,SAASC,wBAAwB,QAAQ,4BAAwB;AACjE,SACEC,eAAe,EACfC,eAAe,QAEV,yBAAqB;AAE5B,kEAAkE,GAClE,OAAO,MAAMC,uBAAuB,4BAA2B;AAE/D,6EAA6E,GAC7E,OAAO,SAASC,wBACdC,MAAyC;IAMzC,OAAO;QACLC,OAAO;QACPC,YAAY;QACZC,MAAMvB,eAAe,aAAa;YAAEwB,QAAQ;QAAmB;QAC/DC,sBACE,yEACA;QACFC,OACE,yEACA,yEACA,2EACA,CAAC,MAAM,EAAEtB,wBAAwBuB,cAAc,GAAG,uBAAuB,CAAC,GAC1E;QACFP,QAAQjB;QACRyB,aAAa1B;QACb2B,cAAcT;QACdU,eAAe;QACfC,iBACE,2EACA;QACFC,gBAAgB,CAACC,OAAOC,QACtB,GAAGD,MAAMN,cAAc,GAAG,IAAI,EAAEO,MAAMP,cAAc,GAAG,cAAc,CAAC,GACtE,uEACA;QACFQ,cAAc,CAACC,UAAY3B,0BAA0B2B,SAAShB;QAC9DiB,QAAQ,CAACC,OAAOC,UACd7B,oBAAoB4B,OAAOC;QAC7BC,OAAOtB;QACPuB,SAASrC;QACTsC,WAAWzC;QACX0C,aAAatC;QACbuC,aAAapC;QACbqC,cAAclC;QACdmC,YAAYxC;QACZyC,YAAYxC;QACZyC,iBAAiB;QACjBC,aAAalC;QACbmC,kBAAkB;IACpB;AACF;AAEA,sFAAsF,GACtF,OAAO,MAAMC,4BAA4BhC,wBAAwB,EAAE,EAAC;AAWpE,OAAO,SAASiC,oBAAoBC,KAA+B;IACjE,MAAM,EAAEC,IAAI,EAAEC,OAAO,EAAEC,MAAM,EAAEC,GAAG,EAAE,GAAGJ;IACvC,gEAAgE;IAChE,MAAM,EAAEK,KAAK,EAAE,GAAG5C,YAAY;QAAE0C;QAAQC;IAAI;IAC5C,MAAM,EAAEE,MAAM,EAAE,GAAG9C,2BAA2ByC,OAAOI,QAAQ,MAAM;IACnE,MAAME,aAAahD,QAAQ,IAAMO,wBAAwBwC,SAAS;QAACA;KAAO;IAC1E,qBACE,KAAC1C;QACCqC,MAAMA;QACNC,SAASA;QACTC,QAAQA;QACRI,YAAYA;;AAGlB;AACAR,oBAAoBS,WAAW,GAAG;AAElC,6EAA6E,GAC7E,OAAO,SAASC,oBAAoBT,KAGnC;IACC,MAAM,EAAEG,MAAM,EAAEC,GAAG,EAAE,GAAGJ;IACxB,qBACE,KAACrC;kBACE,CAACsC,MAAMC,wBACN,KAACH;gBAAoBE,MAAMA;gBAAMC,SAASA;gBAASC,QAAQA;gBAAQC,KAAKA;;;AAIhF;AACAK,oBAAoBD,WAAW,GAAG;AAElC,eAAeT,oBAAmB"}
@@ -1,46 +0,0 @@
1
- /**
2
- * IMPORTING A CONTACT FILE — the contact vocabulary over the shared drawer
3
- * (AGL-2602; the drawer itself is `csv-import-drawer.tsx` since AGL-2621).
4
- *
5
- * The server half is `server/contacts-import.ts`. What this file adds to
6
- * the walk the shared drawer makes is what is particular to people: the
7
- * contact fields and their aliases, the holder's custom fields as further
8
- * targets, the email as the one cell every row needs — judged here by the
9
- * same normalizer the route runs, as a courtesy count — and the line in
10
- * the result that says how many companies the file's company column made.
11
- */
12
- import { type ConsolePluginPageProps } from '@aglyn/aglyn';
13
- export interface ContactImportDrawerProps {
14
- open: boolean;
15
- onClose: () => void;
16
- /**
17
- * The site the file is imported INTO — what the route captures every row
18
- * under — or `null` at the organization level (AGL-2630), where the
19
- * drawer asks which site with a picker and holds the import until one is
20
- * named.
21
- */
22
- hostId: string | null;
23
- /**
24
- * The org document the shell passed, for the consent group's scope
25
- * tokens. Typed as the page prop it is forwarded from, so the contacts
26
- * list mounts the button with the value it already holds and no cast.
27
- */
28
- org?: ConsolePluginPageProps['org'];
29
- }
30
- export declare function ContactImportDrawer(props: ContactImportDrawerProps): import("react").JSX.Element;
31
- export declare namespace ContactImportDrawer {
32
- var displayName: string;
33
- }
34
- /**
35
- * The "Import CSV" action on the contacts list, with the drawer it opens —
36
- * mounted only once opened, so the list pays nothing for it until then.
37
- */
38
- export declare function ContactImportButton(props: {
39
- /** The site the list is read under, or `null` at the organization level. */
40
- hostId: string | null;
41
- org?: ConsolePluginPageProps['org'];
42
- }): import("react").JSX.Element;
43
- export declare namespace ContactImportButton {
44
- var displayName: string;
45
- }
46
- export default ContactImportDrawer;
@@ -1,149 +0,0 @@
1
- /**
2
- * @license
3
- * Copyright 2026 Aglyn LLC
4
- *
5
- * Licensed under the Apache License, Version 2.0 (the "License");
6
- * you may not use this file except in compliance with the License.
7
- * You may obtain a copy of the License at
8
- *
9
- * http://www.apache.org/licenses/LICENSE-2.0
10
- *
11
- * Unless required by applicable law or agreed to in writing, software
12
- * distributed under the License is distributed on an "AS IS" BASIS,
13
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
- * See the License for the specific language governing permissions and
15
- * limitations under the License.
16
- */ 'use client';
17
- import { jsx as _jsx } from "react/jsx-runtime";
18
- /**
19
- * IMPORTING A CONTACT FILE — the contact vocabulary over the shared drawer
20
- * (AGL-2602; the drawer itself is `csv-import-drawer.tsx` since AGL-2621).
21
- *
22
- * The server half is `server/contacts-import.ts`. What this file adds to
23
- * the walk the shared drawer makes is what is particular to people: the
24
- * contact fields and their aliases, the holder's custom fields as further
25
- * targets, the email as the one cell every row needs — judged here by the
26
- * same normalizer the route runs, as a courtesy count — and the line in
27
- * the result that says how many companies the file's company column made.
28
- */ import { CRM_COLLECTIONS, normalizeContactEmail, pluginDocsHelp } from "@aglyn/aglyn";
29
- import { CONTACT_IMPORT_CHUNK_SIZE, CONTACT_IMPORT_FIELD_LABELS, CONTACT_IMPORT_FIELDS, CONTACT_IMPORT_MAX_ROWS, CONTACT_IMPORT_PREVIEW_ROWS, CONTACT_IMPORT_SKIP_LABELS, contactImportSkippedCsv, emptyContactImportResult, guessContactImportMapping, mapContactImportRow, mergeContactImportResults } from "../model/crm-import.js";
30
- import { useFirestore, useFirestoreCollection } from "@aglyn/tenant-feature-instance";
31
- import { Typography } from "@mui/material";
32
- import { collection, limit, query } from "firebase/firestore";
33
- import { useMemo } from "react";
34
- import { crmVisibleToClause, useCrmScope } from "../hooks/use-crm-scope.js";
35
- import { contactImportTemplateCsv } from "../model/contacts-csv.js";
36
- import { CsvImportButton, CsvImportDrawer } from "./csv-import-drawer.js";
37
- /**
38
- * The holder's live custom-field definitions, read only while the drawer
39
- * is open.
40
- *
41
- * A local hook rather than a shared one because the Fields section that
42
- * will own these definitions is landing beside this drawer; when it ships a
43
- * `useContactFieldDefinitions`, this is the read to replace with it. Scoped
44
- * by `visibleTo` the way the contacts listener is, because the rules prove
45
- * a scoped member's query per document and refuse an unfiltered one.
46
- *
47
- * Ordered in memory rather than by the query: `array-contains-any` with an
48
- * `orderBy` on another field needs a composite index the collection does
49
- * not have, and a holder's field list fits in one page.
50
- */ function useImportFieldDefinitions(options) {
51
- const { orgId, visibleToTokens, enabled } = options;
52
- const firestore = useFirestore();
53
- const { data } = useFirestoreCollection(()=>enabled && orgId ? query(collection(firestore, 'orgs', orgId, CRM_COLLECTIONS.contactFields), ...crmVisibleToClause(visibleToTokens), limit(100)) : null, [
54
- firestore,
55
- orgId,
56
- visibleToTokens,
57
- enabled
58
- ], {
59
- idField: '$id'
60
- });
61
- return useMemo(()=>(data != null ? data : []).filter((field)=>!!field.key && !field.retiredAt).sort((a, b)=>{
62
- var _a_order, _b_order;
63
- return Number((_a_order = a.order) != null ? _a_order : 0) - Number((_b_order = b.order) != null ? _b_order : 0);
64
- }), [
65
- data
66
- ]);
67
- }
68
- /** The contact vocabulary, over the holder's custom fields. */ function contactImportVocabulary(fields) {
69
- return {
70
- title: 'Import contacts from CSV',
71
- collection: 'contacts',
72
- help: pluginDocsHelp('contacts', {
73
- anchor: '#import-from-csv'
74
- }),
75
- sitePickerHelperText: 'The site these people are imported into — it decides which of your ' + "sites may see them and whose marketing consent the file's consent " + 'column records.',
76
- intro: 'A CSV with a header row. Match its columns to contact fields ' + 'below, check the preview, then import. A person already in your ' + 'contacts is updated rather than added twice. Up to ' + `${CONTACT_IMPORT_MAX_ROWS.toLocaleString()} rows per file — split a ` + 'larger one.',
77
- fields: CONTACT_IMPORT_FIELDS,
78
- fieldLabels: CONTACT_IMPORT_FIELD_LABELS,
79
- customFields: fields,
80
- requiredField: 'email',
81
- requiredWarning: 'Choose which column holds the email address. It is the one field ' + 'every row needs.',
82
- unusable: (cell)=>!normalizeContactEmail(cell),
83
- unusableNotice: (count, total)=>`${count.toLocaleString()} of ${total.toLocaleString()} rows have no ` + 'usable email address and will be skipped. You can download them ' + 'after the import.',
84
- guessMapping: (columns)=>guessContactImportMapping(columns, fields),
85
- mapRow: (cells, mapping)=>mapContactImportRow(cells, mapping),
86
- route: '/api/crm/contacts-import',
87
- maxRows: CONTACT_IMPORT_MAX_ROWS,
88
- chunkSize: CONTACT_IMPORT_CHUNK_SIZE,
89
- previewRows: CONTACT_IMPORT_PREVIEW_ROWS,
90
- emptyResult: emptyContactImportResult,
91
- mergeResults: (total, chunk, offset)=>mergeContactImportResults(total, chunk, offset),
92
- skipLabels: CONTACT_IMPORT_SKIP_LABELS,
93
- skippedCsv: contactImportSkippedCsv,
94
- skippedFileName: 'skipped-contacts.csv',
95
- templateCsv: ()=>contactImportTemplateCsv(fields),
96
- templateFileName: 'contacts-template.csv',
97
- resultExtras: (result)=>{
98
- const created = result.companiesCreated;
99
- return created ? /*#__PURE__*/ _jsx(Typography, {
100
- variant: "body2",
101
- color: "text.secondary",
102
- children: `${created.toLocaleString()} new ${created === 1 ? 'company' : 'companies'} created from the company column.`
103
- }) : null;
104
- }
105
- };
106
- }
107
- export function ContactImportDrawer(props) {
108
- const { open, onClose, hostId, org } = props;
109
- // The org root and the reader's tokens from the one scope hook (AGL-2614);
110
- // at the organization level no clause, and the site every row is captured
111
- // under is the one the drawer's picker names (AGL-2630).
112
- const { orgId, visibleTo: visibleToTokens } = useCrmScope({
113
- hostId,
114
- org
115
- });
116
- const fields = useImportFieldDefinitions({
117
- orgId,
118
- visibleToTokens,
119
- enabled: open
120
- });
121
- const vocabulary = useMemo(()=>contactImportVocabulary(fields), [
122
- fields
123
- ]);
124
- return /*#__PURE__*/ _jsx(CsvImportDrawer, {
125
- open: open,
126
- onClose: onClose,
127
- hostId: hostId,
128
- vocabulary: vocabulary
129
- });
130
- }
131
- ContactImportDrawer.displayName = 'ContactImportDrawer';
132
- /**
133
- * The "Import CSV" action on the contacts list, with the drawer it opens —
134
- * mounted only once opened, so the list pays nothing for it until then.
135
- */ export function ContactImportButton(props) {
136
- const { hostId, org } = props;
137
- return /*#__PURE__*/ _jsx(CsvImportButton, {
138
- children: (open, onClose)=>/*#__PURE__*/ _jsx(ContactImportDrawer, {
139
- open: open,
140
- onClose: onClose,
141
- hostId: hostId,
142
- org: org
143
- })
144
- });
145
- }
146
- ContactImportButton.displayName = 'ContactImportButton';
147
- export default ContactImportDrawer;
148
-
149
- //# sourceMappingURL=contact-import-drawer.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../../../../../../libs/plugins/crm/src/lib/components/contact-import-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\n/**\n * IMPORTING A CONTACT FILE — the contact vocabulary over the shared drawer\n * (AGL-2602; the drawer itself is `csv-import-drawer.tsx` since AGL-2621).\n *\n * The server half is `server/contacts-import.ts`. What this file adds to\n * the walk the shared drawer makes is what is particular to people: the\n * contact fields and their aliases, the holder's custom fields as further\n * targets, the email as the one cell every row needs — judged here by the\n * same normalizer the route runs, as a courtesy count — and the line in\n * the result that says how many companies the file's company column made.\n */\n\nimport {\n type ConsolePluginPageProps,\n type ContactFieldDefinition,\n CRM_COLLECTIONS,\n normalizeContactEmail,\n pluginDocsHelp,\n} from '@aglyn/aglyn'\nimport {\n CONTACT_IMPORT_CHUNK_SIZE,\n CONTACT_IMPORT_FIELD_LABELS,\n CONTACT_IMPORT_FIELDS,\n CONTACT_IMPORT_MAX_ROWS,\n CONTACT_IMPORT_PREVIEW_ROWS,\n CONTACT_IMPORT_SKIP_LABELS,\n type ContactImportChunkResult,\n type ContactImportField,\n type ContactImportRawRow,\n type ContactImportSkippedRow,\n contactImportSkippedCsv,\n emptyContactImportResult,\n guessContactImportMapping,\n mapContactImportRow,\n mergeContactImportResults,\n} from '../model/crm-import'\nimport { useFirestore, useFirestoreCollection } from '@aglyn/tenant-feature-instance'\nimport { Typography } from '@mui/material'\nimport { collection, limit, query } from 'firebase/firestore'\nimport { useMemo } from 'react'\nimport { crmVisibleToClause, useCrmScope } from '../hooks/use-crm-scope'\nimport { contactImportTemplateCsv } from '../model/contacts-csv'\nimport {\n CsvImportButton,\n CsvImportDrawer,\n type CsvImportVocabulary,\n} from './csv-import-drawer'\n\nexport interface ContactImportDrawerProps {\n open: boolean\n onClose: () => void\n /**\n * The site the file is imported INTO — what the route captures every row\n * under — or `null` at the organization level (AGL-2630), where the\n * drawer asks which site with a picker and holds the import until one is\n * named.\n */\n hostId: string | null\n /**\n * The org document the shell passed, for the consent group's scope\n * tokens. Typed as the page prop it is forwarded from, so the contacts\n * list mounts the button with the value it already holds and no cast.\n */\n org?: ConsolePluginPageProps['org']\n}\n\n/**\n * The holder's live custom-field definitions, read only while the drawer\n * is open.\n *\n * A local hook rather than a shared one because the Fields section that\n * will own these definitions is landing beside this drawer; when it ships a\n * `useContactFieldDefinitions`, this is the read to replace with it. Scoped\n * by `visibleTo` the way the contacts listener is, because the rules prove\n * a scoped member's query per document and refuse an unfiltered one.\n *\n * Ordered in memory rather than by the query: `array-contains-any` with an\n * `orderBy` on another field needs a composite index the collection does\n * not have, and a holder's field list fits in one page.\n */\nfunction useImportFieldDefinitions(options: {\n orgId: string | null | undefined\n /** The reader's tokens, or `null` at the organization level — no clause. */\n visibleToTokens: readonly string[] | null\n enabled: boolean\n}): ContactFieldDefinition[] {\n const { orgId, visibleToTokens, enabled } = options\n const firestore = useFirestore()\n const { data } = useFirestoreCollection<ContactFieldDefinition & { $id: string }>(\n () =>\n enabled && orgId\n ? query(\n collection(firestore, 'orgs', orgId, CRM_COLLECTIONS.contactFields),\n ...crmVisibleToClause(visibleToTokens),\n limit(100),\n )\n : null,\n [firestore, orgId, visibleToTokens, enabled],\n { idField: '$id' },\n )\n return useMemo(\n () =>\n (data ?? [])\n .filter((field) => !!field.key && !field.retiredAt)\n .sort((a, b) => Number(a.order ?? 0) - Number(b.order ?? 0)),\n [data],\n )\n}\n\n/** The contact vocabulary, over the holder's custom fields. */\nfunction contactImportVocabulary(\n fields: readonly ContactFieldDefinition[],\n): CsvImportVocabulary<\n ContactImportField,\n ContactImportRawRow & Record<string, unknown>,\n ContactImportSkippedRow\n> {\n return {\n title: 'Import contacts from CSV',\n collection: 'contacts',\n help: pluginDocsHelp('contacts', { anchor: '#import-from-csv' }),\n sitePickerHelperText:\n 'The site these people are imported into — it decides which of your ' +\n \"sites may see them and whose marketing consent the file's consent \" +\n 'column records.',\n intro:\n 'A CSV with a header row. Match its columns to contact fields ' +\n 'below, check the preview, then import. A person already in your ' +\n 'contacts is updated rather than added twice. Up to ' +\n `${CONTACT_IMPORT_MAX_ROWS.toLocaleString()} rows per file — split a ` +\n 'larger one.',\n fields: CONTACT_IMPORT_FIELDS,\n fieldLabels: CONTACT_IMPORT_FIELD_LABELS,\n customFields: fields,\n requiredField: 'email',\n requiredWarning:\n 'Choose which column holds the email address. It is the one field ' +\n 'every row needs.',\n unusable: (cell) => !normalizeContactEmail(cell),\n unusableNotice: (count, total) =>\n `${count.toLocaleString()} of ${total.toLocaleString()} rows have no ` +\n 'usable email address and will be skipped. You can download them ' +\n 'after the import.',\n guessMapping: (columns) => guessContactImportMapping(columns, fields),\n mapRow: (cells, mapping) =>\n mapContactImportRow(cells, mapping) as ContactImportRawRow & Record<string, unknown>,\n route: '/api/crm/contacts-import',\n maxRows: CONTACT_IMPORT_MAX_ROWS,\n chunkSize: CONTACT_IMPORT_CHUNK_SIZE,\n previewRows: CONTACT_IMPORT_PREVIEW_ROWS,\n emptyResult: emptyContactImportResult,\n mergeResults: (total, chunk, offset) =>\n mergeContactImportResults(\n total as ContactImportChunkResult,\n chunk as ContactImportChunkResult,\n offset,\n ),\n skipLabels: CONTACT_IMPORT_SKIP_LABELS,\n skippedCsv: contactImportSkippedCsv,\n skippedFileName: 'skipped-contacts.csv',\n templateCsv: () => contactImportTemplateCsv(fields),\n templateFileName: 'contacts-template.csv',\n resultExtras: (result) => {\n const created = (result as ContactImportChunkResult).companiesCreated\n return created ? (\n <Typography variant=\"body2\" color=\"text.secondary\">\n {`${created.toLocaleString()} new ${\n created === 1 ? 'company' : 'companies'\n } created from the company column.`}\n </Typography>\n ) : null\n },\n }\n}\n\nexport function ContactImportDrawer(props: ContactImportDrawerProps) {\n const { open, onClose, hostId, org } = props\n // The org root and the reader's tokens from the one scope hook (AGL-2614);\n // at the organization level no clause, and the site every row is captured\n // under is the one the drawer's picker names (AGL-2630).\n const { orgId, visibleTo: visibleToTokens } = useCrmScope({ hostId, org })\n const fields = useImportFieldDefinitions({\n orgId,\n visibleToTokens,\n enabled: open,\n })\n const vocabulary = useMemo(() => contactImportVocabulary(fields), [fields])\n return (\n <CsvImportDrawer\n open={open}\n onClose={onClose}\n hostId={hostId}\n vocabulary={vocabulary}\n />\n )\n}\nContactImportDrawer.displayName = 'ContactImportDrawer'\n\n/**\n * The \"Import CSV\" action on the contacts list, with the drawer it opens —\n * mounted only once opened, so the list pays nothing for it until then.\n */\nexport function ContactImportButton(props: {\n /** The site the list is read under, or `null` at the organization level. */\n hostId: string | null\n org?: ConsolePluginPageProps['org']\n}) {\n const { hostId, org } = props\n return (\n <CsvImportButton>\n {(open, onClose) => (\n <ContactImportDrawer open={open} onClose={onClose} hostId={hostId} org={org} />\n )}\n </CsvImportButton>\n )\n}\nContactImportButton.displayName = 'ContactImportButton'\n\nexport default ContactImportDrawer\n"],"names":["CRM_COLLECTIONS","normalizeContactEmail","pluginDocsHelp","CONTACT_IMPORT_CHUNK_SIZE","CONTACT_IMPORT_FIELD_LABELS","CONTACT_IMPORT_FIELDS","CONTACT_IMPORT_MAX_ROWS","CONTACT_IMPORT_PREVIEW_ROWS","CONTACT_IMPORT_SKIP_LABELS","contactImportSkippedCsv","emptyContactImportResult","guessContactImportMapping","mapContactImportRow","mergeContactImportResults","useFirestore","useFirestoreCollection","Typography","collection","limit","query","useMemo","crmVisibleToClause","useCrmScope","contactImportTemplateCsv","CsvImportButton","CsvImportDrawer","useImportFieldDefinitions","options","orgId","visibleToTokens","enabled","firestore","data","contactFields","idField","filter","field","key","retiredAt","sort","a","b","Number","order","contactImportVocabulary","fields","title","help","anchor","sitePickerHelperText","intro","toLocaleString","fieldLabels","customFields","requiredField","requiredWarning","unusable","cell","unusableNotice","count","total","guessMapping","columns","mapRow","cells","mapping","route","maxRows","chunkSize","previewRows","emptyResult","mergeResults","chunk","offset","skipLabels","skippedCsv","skippedFileName","templateCsv","templateFileName","resultExtras","result","created","companiesCreated","variant","color","ContactImportDrawer","props","open","onClose","hostId","org","visibleTo","vocabulary","displayName","ContactImportButton"],"mappings":"AAAA;;;;;;;;;;;;;;;CAeC,GACD;;AAEA;;;;;;;;;;CAUC,GAED,SAGEA,eAAe,EACfC,qBAAqB,EACrBC,cAAc,QACT,eAAc;AACrB,SACEC,yBAAyB,EACzBC,2BAA2B,EAC3BC,qBAAqB,EACrBC,uBAAuB,EACvBC,2BAA2B,EAC3BC,0BAA0B,EAK1BC,uBAAuB,EACvBC,wBAAwB,EACxBC,yBAAyB,EACzBC,mBAAmB,EACnBC,yBAAyB,QACpB,yBAAqB;AAC5B,SAASC,YAAY,EAAEC,sBAAsB,QAAQ,iCAAgC;AACrF,SAASC,UAAU,QAAQ,gBAAe;AAC1C,SAASC,UAAU,EAAEC,KAAK,EAAEC,KAAK,QAAQ,qBAAoB;AAC7D,SAASC,OAAO,QAAQ,QAAO;AAC/B,SAASC,kBAAkB,EAAEC,WAAW,QAAQ,4BAAwB;AACxE,SAASC,wBAAwB,QAAQ,2BAAuB;AAChE,SACEC,eAAe,EACfC,eAAe,QAEV,yBAAqB;AAoB5B;;;;;;;;;;;;;CAaC,GACD,SAASC,0BAA0BC,OAKlC;IACC,MAAM,EAAEC,KAAK,EAAEC,eAAe,EAAEC,OAAO,EAAE,GAAGH;IAC5C,MAAMI,YAAYjB;IAClB,MAAM,EAAEkB,IAAI,EAAE,GAAGjB,uBACf,IACEe,WAAWF,QACPT,MACEF,WAAWc,WAAW,QAAQH,OAAO5B,gBAAgBiC,aAAa,MAC/DZ,mBAAmBQ,kBACtBX,MAAM,QAER,MACN;QAACa;QAAWH;QAAOC;QAAiBC;KAAQ,EAC5C;QAAEI,SAAS;IAAM;IAEnB,OAAOd,QACL,IACE,CAACY,eAAAA,OAAQ,EAAE,EACRG,MAAM,CAAC,CAACC,QAAU,CAAC,CAACA,MAAMC,GAAG,IAAI,CAACD,MAAME,SAAS,EACjDC,IAAI,CAAC,CAACC,GAAGC;gBAAaD,UAAuBC;mBAA9BC,QAAOF,WAAAA,EAAEG,KAAK,YAAPH,WAAW,KAAKE,QAAOD,WAAAA,EAAEE,KAAK,YAAPF,WAAW;YAC7D;QAACT;KAAK;AAEV;AAEA,6DAA6D,GAC7D,SAASY,wBACPC,MAAyC;IAMzC,OAAO;QACLC,OAAO;QACP7B,YAAY;QACZ8B,MAAM7C,eAAe,YAAY;YAAE8C,QAAQ;QAAmB;QAC9DC,sBACE,wEACA,uEACA;QACFC,OACE,kEACA,qEACA,wDACA,GAAG5C,wBAAwB6C,cAAc,GAAG,yBAAyB,CAAC,GACtE;QACFN,QAAQxC;QACR+C,aAAahD;QACbiD,cAAcR;QACdS,eAAe;QACfC,iBACE,sEACA;QACFC,UAAU,CAACC,OAAS,CAACxD,sBAAsBwD;QAC3CC,gBAAgB,CAACC,OAAOC,QACtB,GAAGD,MAAMR,cAAc,GAAG,IAAI,EAAES,MAAMT,cAAc,GAAG,cAAc,CAAC,GACtE,qEACA;QACFU,cAAc,CAACC,UAAYnD,0BAA0BmD,SAASjB;QAC9DkB,QAAQ,CAACC,OAAOC,UACdrD,oBAAoBoD,OAAOC;QAC7BC,OAAO;QACPC,SAAS7D;QACT8D,WAAWjE;QACXkE,aAAa9D;QACb+D,aAAa5D;QACb6D,cAAc,CAACX,OAAOY,OAAOC,SAC3B5D,0BACE+C,OACAY,OACAC;QAEJC,YAAYlE;QACZmE,YAAYlE;QACZmE,iBAAiB;QACjBC,aAAa,IAAMtD,yBAAyBsB;QAC5CiC,kBAAkB;QAClBC,cAAc,CAACC;YACb,MAAMC,UAAU,AAACD,OAAoCE,gBAAgB;YACrE,OAAOD,wBACL,KAACjE;gBAAWmE,SAAQ;gBAAQC,OAAM;0BAC/B,GAAGH,QAAQ9B,cAAc,GAAG,KAAK,EAChC8B,YAAY,IAAI,YAAY,YAC7B,iCAAiC,CAAC;iBAEnC;QACN;IACF;AACF;AAEA,OAAO,SAASI,oBAAoBC,KAA+B;IACjE,MAAM,EAAEC,IAAI,EAAEC,OAAO,EAAEC,MAAM,EAAEC,GAAG,EAAE,GAAGJ;IACvC,2EAA2E;IAC3E,0EAA0E;IAC1E,yDAAyD;IACzD,MAAM,EAAE1D,KAAK,EAAE+D,WAAW9D,eAAe,EAAE,GAAGP,YAAY;QAAEmE;QAAQC;IAAI;IACxE,MAAM7C,SAASnB,0BAA0B;QACvCE;QACAC;QACAC,SAASyD;IACX;IACA,MAAMK,aAAaxE,QAAQ,IAAMwB,wBAAwBC,SAAS;QAACA;KAAO;IAC1E,qBACE,KAACpB;QACC8D,MAAMA;QACNC,SAASA;QACTC,QAAQA;QACRG,YAAYA;;AAGlB;AACAP,oBAAoBQ,WAAW,GAAG;AAElC;;;CAGC,GACD,OAAO,SAASC,oBAAoBR,KAInC;IACC,MAAM,EAAEG,MAAM,EAAEC,GAAG,EAAE,GAAGJ;IACxB,qBACE,KAAC9D;kBACE,CAAC+D,MAAMC,wBACN,KAACH;gBAAoBE,MAAMA;gBAAMC,SAASA;gBAASC,QAAQA;gBAAQC,KAAKA;;;AAIhF;AACAI,oBAAoBD,WAAW,GAAG;AAElC,eAAeR,oBAAmB"}
@@ -1,39 +0,0 @@
1
- import type { CrmExportResource } from '../model/crm-csv';
2
- export interface CrmExportAllButtonProps {
3
- /** Which table to take a complete copy of. */
4
- resource: CrmExportResource;
5
- /** The organization whose records these are; null holds the button. */
6
- orgId: string | null;
7
- /**
8
- * The site being read as.
9
- *
10
- * Required for contacts — the file is written through one holder's facet
11
- * and a facet is per site — and for a scoped reader's leads. Null at the
12
- * organization level, where an org-wide member takes every site's leads
13
- * in one file.
14
- */
15
- hostId: string | null;
16
- disabled?: boolean;
17
- }
18
- /**
19
- * EXPORT ALL — the whole collection, not the loaded window (AGL-2662).
20
- *
21
- * Beside "Export CSV", which writes the rows on screen. The two are
22
- * deliberately both offered and deliberately named apart: a selection's
23
- * file is what somebody just picked, and this is the audience.
24
- *
25
- * ## The response is checked, not trusted
26
- *
27
- * The route reports a `count()` aggregate in `X-Aglyn-Export-Rows`, taken
28
- * before its first page. A stream that dies halfway produces a perfectly
29
- * well-formed shorter file, and nothing about the bytes says it is short —
30
- * which is exactly how the window-sized export stayed invisible for as long
31
- * as it did. A body with fewer rows than promised is REFUSED rather than
32
- * saved, because a partial audience saved under a confident name is worse
33
- * than no file.
34
- */
35
- export declare function CrmExportAllButton(props: CrmExportAllButtonProps): import("react").JSX.Element;
36
- export declare namespace CrmExportAllButton {
37
- var displayName: string;
38
- }
39
- export default CrmExportAllButton;
@@ -1,98 +0,0 @@
1
- /**
2
- * @license
3
- * Copyright 2026 Aglyn LLC
4
- *
5
- * Licensed under the Apache License, Version 2.0 (the "License");
6
- * you may not use this file except in compliance with the License.
7
- * You may obtain a copy of the License at
8
- *
9
- * http://www.apache.org/licenses/LICENSE-2.0
10
- *
11
- * Unless required by applicable law or agreed to in writing, software
12
- * distributed under the License is distributed on an "AS IS" BASIS,
13
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
- * See the License for the specific language governing permissions and
15
- * limitations under the License.
16
- */ 'use client';
17
- import { jsx as _jsx } from "react/jsx-runtime";
18
- import { countCsvDataRows } from "@aglyn/aglyn";
19
- import { authorizedFetch } from "@aglyn/shared-util-http/authorized-token";
20
- import { useUser } from "@aglyn/tenant-feature-instance";
21
- import { Button } from "@mui/material";
22
- import { useSnackbar } from "notistack";
23
- import { useCallback, useState } from "react";
24
- import { downloadTextFile } from "../model/contacts-csv.js";
25
- /** The header the export route promises its row count in. */ const EXPORT_ROWS_HEADER = 'X-Aglyn-Export-Rows';
26
- /**
27
- * EXPORT ALL — the whole collection, not the loaded window (AGL-2662).
28
- *
29
- * Beside "Export CSV", which writes the rows on screen. The two are
30
- * deliberately both offered and deliberately named apart: a selection's
31
- * file is what somebody just picked, and this is the audience.
32
- *
33
- * ## The response is checked, not trusted
34
- *
35
- * The route reports a `count()` aggregate in `X-Aglyn-Export-Rows`, taken
36
- * before its first page. A stream that dies halfway produces a perfectly
37
- * well-formed shorter file, and nothing about the bytes says it is short —
38
- * which is exactly how the window-sized export stayed invisible for as long
39
- * as it did. A body with fewer rows than promised is REFUSED rather than
40
- * saved, because a partial audience saved under a confident name is worse
41
- * than no file.
42
- */ export function CrmExportAllButton(props) {
43
- const { resource, orgId, hostId, disabled } = props;
44
- const { data: user } = useUser();
45
- const { enqueueSnackbar } = useSnackbar();
46
- const [busy, setBusy] = useState(false);
47
- const handleExport = useCallback(async ()=>{
48
- if (!orgId || busy) return;
49
- setBusy(true);
50
- try {
51
- var _response_headers_get;
52
- const params = new URLSearchParams({
53
- orgId,
54
- resource
55
- });
56
- if (hostId) params.set('hostId', hostId);
57
- const response = await authorizedFetch(user, `/api/crm/export?${params.toString()}`);
58
- if (!response.ok) {
59
- var _ref;
60
- const failure = await response.json().catch(()=>({}));
61
- throw new Error((_ref = failure == null ? void 0 : failure.error) != null ? _ref : 'Export failed');
62
- }
63
- const text = await response.text();
64
- const promised = Number((_response_headers_get = response.headers.get(EXPORT_ROWS_HEADER)) != null ? _response_headers_get : '');
65
- const received = countCsvDataRows(text);
66
- if (Number.isFinite(promised) && received < promised) {
67
- enqueueSnackbar(`Export incomplete — ${received} of ${promised} rows arrived. ` + 'Nothing was saved; try again.', {
68
- variant: 'error'
69
- });
70
- return;
71
- }
72
- downloadTextFile(`${resource}.csv`, 'text/csv', text);
73
- } catch (error) {
74
- enqueueSnackbar(error instanceof Error ? error.message : 'Export failed', {
75
- variant: 'error'
76
- });
77
- } finally{
78
- setBusy(false);
79
- }
80
- }, [
81
- orgId,
82
- hostId,
83
- resource,
84
- user,
85
- busy,
86
- enqueueSnackbar
87
- ]);
88
- return /*#__PURE__*/ _jsx(Button, {
89
- size: "small",
90
- disabled: disabled || busy || !orgId,
91
- onClick: ()=>void handleExport(),
92
- children: busy ? 'Exporting…' : 'Export all…'
93
- });
94
- }
95
- CrmExportAllButton.displayName = 'CrmExportAllButton';
96
- export default CrmExportAllButton;
97
-
98
- //# sourceMappingURL=crm-export-all-button.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../../../../../../libs/plugins/crm/src/lib/components/crm-export-all-button.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 countCsvDataRows,\n} from '@aglyn/aglyn'\nimport { authorizedFetch } from '@aglyn/shared-util-http/authorized-token'\nimport { useUser } from '@aglyn/tenant-feature-instance'\nimport { Button } from '@mui/material'\nimport { useSnackbar } from 'notistack'\nimport { useCallback, useState } from 'react'\nimport { downloadTextFile } from '../model/contacts-csv'\nimport type { CrmExportResource } from '../model/crm-csv'\n\n/** The header the export route promises its row count in. */\nconst EXPORT_ROWS_HEADER = 'X-Aglyn-Export-Rows'\n\nexport interface CrmExportAllButtonProps {\n /** Which table to take a complete copy of. */\n resource: CrmExportResource\n /** The organization whose records these are; null holds the button. */\n orgId: string | null\n /**\n * The site being read as.\n *\n * Required for contacts — the file is written through one holder's facet\n * and a facet is per site — and for a scoped reader's leads. Null at the\n * organization level, where an org-wide member takes every site's leads\n * in one file.\n */\n hostId: string | null\n disabled?: boolean\n}\n\n/**\n * EXPORT ALL — the whole collection, not the loaded window (AGL-2662).\n *\n * Beside \"Export CSV\", which writes the rows on screen. The two are\n * deliberately both offered and deliberately named apart: a selection's\n * file is what somebody just picked, and this is the audience.\n *\n * ## The response is checked, not trusted\n *\n * The route reports a `count()` aggregate in `X-Aglyn-Export-Rows`, taken\n * before its first page. A stream that dies halfway produces a perfectly\n * well-formed shorter file, and nothing about the bytes says it is short —\n * which is exactly how the window-sized export stayed invisible for as long\n * as it did. A body with fewer rows than promised is REFUSED rather than\n * saved, because a partial audience saved under a confident name is worse\n * than no file.\n */\nexport function CrmExportAllButton(props: CrmExportAllButtonProps) {\n const { resource, orgId, hostId, disabled } = props\n const { data: user } = useUser()\n const { enqueueSnackbar } = useSnackbar()\n const [busy, setBusy] = useState(false)\n\n const handleExport = useCallback(async () => {\n if (!orgId || busy) return\n setBusy(true)\n try {\n const params = new URLSearchParams({ orgId, resource })\n if (hostId) params.set('hostId', hostId)\n const response = await authorizedFetch(\n user,\n `/api/crm/export?${params.toString()}`,\n )\n if (!response.ok) {\n const failure = await response.json().catch(() => ({}))\n throw new Error(failure?.error ?? 'Export failed')\n }\n const text = await response.text()\n const promised = Number(response.headers.get(EXPORT_ROWS_HEADER) ?? '')\n const received = countCsvDataRows(text)\n if (Number.isFinite(promised) && received < promised) {\n enqueueSnackbar(\n `Export incomplete — ${received} of ${promised} rows arrived. ` +\n 'Nothing was saved; try again.',\n { variant: 'error' },\n )\n return\n }\n downloadTextFile(`${resource}.csv`, 'text/csv', text)\n } catch (error) {\n enqueueSnackbar(\n error instanceof Error ? error.message : 'Export failed',\n { variant: 'error' },\n )\n } finally {\n setBusy(false)\n }\n }, [orgId, hostId, resource, user, busy, enqueueSnackbar])\n\n return (\n <Button\n size=\"small\"\n disabled={disabled || busy || !orgId}\n onClick={() => void handleExport()}\n >\n {busy ? 'Exporting…' : 'Export all…'}\n </Button>\n )\n}\nCrmExportAllButton.displayName = 'CrmExportAllButton'\n\nexport default CrmExportAllButton\n"],"names":["countCsvDataRows","authorizedFetch","useUser","Button","useSnackbar","useCallback","useState","downloadTextFile","EXPORT_ROWS_HEADER","CrmExportAllButton","props","resource","orgId","hostId","disabled","data","user","enqueueSnackbar","busy","setBusy","handleExport","response","params","URLSearchParams","set","toString","ok","failure","json","catch","Error","error","text","promised","Number","headers","get","received","isFinite","variant","message","size","onClick","displayName"],"mappings":"AAAA;;;;;;;;;;;;;;;CAeC,GACD;;AAEA,SACEA,gBAAgB,QACX,eAAc;AACrB,SAASC,eAAe,QAAQ,2CAA0C;AAC1E,SAASC,OAAO,QAAQ,iCAAgC;AACxD,SAASC,MAAM,QAAQ,gBAAe;AACtC,SAASC,WAAW,QAAQ,YAAW;AACvC,SAASC,WAAW,EAAEC,QAAQ,QAAQ,QAAO;AAC7C,SAASC,gBAAgB,QAAQ,2BAAuB;AAGxD,2DAA2D,GAC3D,MAAMC,qBAAqB;AAmB3B;;;;;;;;;;;;;;;;CAgBC,GACD,OAAO,SAASC,mBAAmBC,KAA8B;IAC/D,MAAM,EAAEC,QAAQ,EAAEC,KAAK,EAAEC,MAAM,EAAEC,QAAQ,EAAE,GAAGJ;IAC9C,MAAM,EAAEK,MAAMC,IAAI,EAAE,GAAGd;IACvB,MAAM,EAAEe,eAAe,EAAE,GAAGb;IAC5B,MAAM,CAACc,MAAMC,QAAQ,GAAGb,SAAS;IAEjC,MAAMc,eAAef,YAAY;QAC/B,IAAI,CAACO,SAASM,MAAM;QACpBC,QAAQ;QACR,IAAI;gBAYsBE;YAXxB,MAAMC,SAAS,IAAIC,gBAAgB;gBAAEX;gBAAOD;YAAS;YACrD,IAAIE,QAAQS,OAAOE,GAAG,CAAC,UAAUX;YACjC,MAAMQ,WAAW,MAAMpB,gBACrBe,MACA,CAAC,gBAAgB,EAAEM,OAAOG,QAAQ,IAAI;YAExC,IAAI,CAACJ,SAASK,EAAE,EAAE;;gBAChB,MAAMC,UAAU,MAAMN,SAASO,IAAI,GAAGC,KAAK,CAAC,IAAO,CAAA,CAAC,CAAA;gBACpD,MAAM,IAAIC,cAAMH,2BAAAA,QAASI,KAAK,mBAAI;YACpC;YACA,MAAMC,OAAO,MAAMX,SAASW,IAAI;YAChC,MAAMC,WAAWC,QAAOb,wBAAAA,SAASc,OAAO,CAACC,GAAG,CAAC5B,+BAArBa,wBAA4C;YACpE,MAAMgB,WAAWrC,iBAAiBgC;YAClC,IAAIE,OAAOI,QAAQ,CAACL,aAAaI,WAAWJ,UAAU;gBACpDhB,gBACE,CAAC,oBAAoB,EAAEoB,SAAS,IAAI,EAAEJ,SAAS,eAAe,CAAC,GAC7D,iCACF;oBAAEM,SAAS;gBAAQ;gBAErB;YACF;YACAhC,iBAAiB,GAAGI,SAAS,IAAI,CAAC,EAAE,YAAYqB;QAClD,EAAE,OAAOD,OAAO;YACdd,gBACEc,iBAAiBD,QAAQC,MAAMS,OAAO,GAAG,iBACzC;gBAAED,SAAS;YAAQ;QAEvB,SAAU;YACRpB,QAAQ;QACV;IACF,GAAG;QAACP;QAAOC;QAAQF;QAAUK;QAAME;QAAMD;KAAgB;IAEzD,qBACE,KAACd;QACCsC,MAAK;QACL3B,UAAUA,YAAYI,QAAQ,CAACN;QAC/B8B,SAAS,IAAM,KAAKtB;kBAEnBF,OAAO,eAAe;;AAG7B;AACAT,mBAAmBkC,WAAW,GAAG;AAEjC,eAAelC,mBAAkB"}
@@ -1,139 +0,0 @@
1
- /**
2
- * IMPORTING A CSV INTO A CRM COLLECTION — the screen, for whichever
3
- * collection (AGL-2602, shared since AGL-2621).
4
- *
5
- * The contact import settled the walk from a file on disk to a result the
6
- * operator can act on: choose the file, read what is in it, match its
7
- * columns to fields with the first row beside each, preview the ten rows
8
- * the mapping produces, run it in bounded requests with a progress bar,
9
- * and report what was added, updated and skipped with the skipped rows as
10
- * a file to fix. A companies file walks the same path with a different
11
- * vocabulary, so the walk lives here once and each collection hands in a
12
- * {@link CsvImportVocabulary}: its fields and their labels, the one field
13
- * every row needs, its route, its tally, its template.
14
- *
15
- * ## The file is read in the browser, and judged on the server
16
- *
17
- * `parseCsv` — the same parser the list import and the dataset import run
18
- * — turns the file into cells here, so the operator can map and preview
19
- * without a round trip and without uploading a file they may still decide
20
- * not to import. Nothing is VALIDATED here beyond counting the rows whose
21
- * required cell is unusable, and that count is a courtesy: every row is
22
- * judged by the route, through the normalizers every other door uses, and
23
- * the numbers on the result panel are the server's.
24
- *
25
- * ## Bounded requests, and closing stops them
26
- *
27
- * A chunk per request, as many requests as the file needs, and a progress
28
- * bar between them. Closing the drawer mid-run stops the loop after the
29
- * request in flight; the rows already written stay written and the result
30
- * panel says how far it got. There is no durable job to resume — an import
31
- * is idempotent by construction (the door dedupes on the address, or the
32
- * domain and the name), so running the same file again finishes what a
33
- * closed drawer left, reporting the earlier rows as merged.
34
- */
35
- import { type ImportChunkResult, type ImportSkippedRow } from '@aglyn/aglyn';
36
- import { HelpTip } from '@aglyn/shared-ui-jsx';
37
- import { type ComponentProps, type ReactNode } from 'react';
38
- /** A column's target: a standard field, or a custom one as `custom:<key>`. */
39
- export type CsvImportTarget<F extends string> = F | `custom:${string}`;
40
- /** Column index → target. A column absent from the map is not imported. */
41
- export type CsvImportMapping<F extends string> = Record<number, CsvImportTarget<F>>;
42
- /** A custom field a column may be mapped to, when the collection has any. */
43
- export interface CsvImportCustomField {
44
- key: string;
45
- label: string;
46
- }
47
- /**
48
- * Everything one collection's import says for itself. Pure values and pure
49
- * functions, so a vocabulary is built once outside React and handed in.
50
- */
51
- export interface CsvImportVocabulary<F extends string, R extends Record<string, unknown>, S extends ImportSkippedRow<string>> {
52
- /** The drawer's title — "Import contacts from CSV". */
53
- title: string;
54
- /**
55
- * What the import is called where the `importMapping` zone names it —
56
- * `contacts`, `companies`, `deals`, `leads` (AGL-2917). Absent, the drawer
57
- * hosts no zone.
58
- */
59
- collection?: string;
60
- help: ComponentProps<typeof HelpTip>;
61
- /**
62
- * What the site picker's answer decides, said under it at the
63
- * organization level (AGL-2630). Absent, the picker's own sentence.
64
- */
65
- sitePickerHelperText?: string;
66
- /** The paragraph under the title. */
67
- intro: string;
68
- /** The standard targets, in the order the mapping menu lists them. */
69
- fields: readonly F[];
70
- fieldLabels: Record<F, string>;
71
- /** Custom targets, offered after the standard ones; none for most collections. */
72
- customFields?: readonly CsvImportCustomField[];
73
- /** The one field every row needs, and what the drawer says when it is unmapped. */
74
- requiredField: F;
75
- requiredWarning: string;
76
- /**
77
- * Whether a required cell is one the server would refuse — the courtesy
78
- * count the preview shows. Absent, only a blank cell counts.
79
- */
80
- unusable?: (cell: string) => boolean;
81
- /** The preview's sentence about them. */
82
- unusableNotice: (count: number, total: number) => string;
83
- guessMapping: (columns: readonly string[]) => CsvImportMapping<F>;
84
- mapRow: (cells: readonly string[], mapping: CsvImportMapping<F>) => R;
85
- /** The browser-side URL of the route one chunk is posted to. */
86
- route: string;
87
- maxRows: number;
88
- chunkSize: number;
89
- previewRows: number;
90
- emptyResult: () => ImportChunkResult<S>;
91
- mergeResults: (total: ImportChunkResult<S>, chunk: ImportChunkResult<S>, offset: number) => ImportChunkResult<S>;
92
- skipLabels: Record<S['reason'], string>;
93
- skippedCsv: (columns: readonly string[], entries: readonly {
94
- cells: readonly string[];
95
- reason: S['reason'];
96
- }[]) => string;
97
- skippedFileName: string;
98
- /** The export's header over no rows. */
99
- templateCsv: () => string;
100
- templateFileName: string;
101
- /** The result panel's collection-specific lines, when there are any. */
102
- resultExtras?: (result: ImportChunkResult<S>) => ReactNode;
103
- /**
104
- * A collection-specific warning about the mapped file, shown above the
105
- * preview before anything is sent — a value the server will refuse that
106
- * the operator can fix first. Given every row as `mapRow` reads it;
107
- * answers nothing when the file is fine.
108
- */
109
- rowsNotice?: (rows: readonly R[]) => ReactNode;
110
- }
111
- export interface CsvImportDrawerProps<F extends string, R extends Record<string, unknown>, S extends ImportSkippedRow<string>> {
112
- open: boolean;
113
- onClose: () => void;
114
- /**
115
- * The site the file is imported INTO — what the route files every row
116
- * under — or `null` at the organization level (AGL-2630), where the
117
- * drawer asks which site with a picker and holds the import until one is
118
- * named.
119
- */
120
- hostId: string | null;
121
- vocabulary: CsvImportVocabulary<F, R, S>;
122
- }
123
- export declare function CsvImportDrawer<F extends string, R extends Record<string, unknown>, S extends ImportSkippedRow<string>>(props: CsvImportDrawerProps<F, R, S>): import("react").JSX.Element;
124
- export declare namespace CsvImportDrawer {
125
- var displayName: string;
126
- }
127
- /**
128
- * An "Import CSV" button that mounts its drawer only once it has been
129
- * opened, so the list pays nothing — no hooks, no listeners — for a
130
- * feature the operator has not reached for.
131
- */
132
- export declare function CsvImportButton(props: {
133
- label?: string;
134
- children: (open: boolean, onClose: () => void) => ReactNode;
135
- }): import("react").JSX.Element;
136
- export declare namespace CsvImportButton {
137
- var displayName: string;
138
- }
139
- export default CsvImportDrawer;