@graph8/sdk 0.370.0 → 0.374.0

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 (646) hide show
  1. package/README.md +22 -3
  2. package/blocks/_foundation/README.md +61 -0
  3. package/blocks/_foundation/block.json +57 -0
  4. package/blocks/_foundation/components/auth-gate.tsx +363 -0
  5. package/blocks/_foundation/components/confirm-spend-dialog.tsx +15 -8
  6. package/blocks/_foundation/components/empty-state.tsx +5 -2
  7. package/blocks/_foundation/components/list-select.tsx +112 -0
  8. package/blocks/_foundation/components/paging-notices.tsx +55 -0
  9. package/blocks/_foundation/components/screen/detail-panel.tsx +2 -1
  10. package/blocks/_foundation/components/screen/filter-controls.tsx +92 -0
  11. package/blocks/_foundation/components/screen/index.ts +1 -0
  12. package/blocks/_foundation/components/screen/split-view.tsx +1 -1
  13. package/blocks/_foundation/hooks/use-all-pages.ts +54 -0
  14. package/blocks/_foundation/hooks/use-load-more-list.ts +61 -0
  15. package/blocks/_foundation/hooks/use-url-filters.ts +93 -0
  16. package/blocks/_foundation/lib/paging.ts +57 -0
  17. package/blocks/_foundation/lib/use-debounced-value.ts +13 -0
  18. package/blocks/_foundation/server/auth.ts +815 -0
  19. package/blocks/agents/README.md +81 -4
  20. package/blocks/agents/block.json +311 -2
  21. package/blocks/agents/components/agent-activity.tsx +112 -0
  22. package/blocks/agents/components/agent-approvals.tsx +135 -0
  23. package/blocks/agents/components/agent-builder.tsx +17 -3
  24. package/blocks/agents/components/agent-conversations.tsx +143 -0
  25. package/blocks/agents/components/agent-knowledge-panel.tsx +2 -2
  26. package/blocks/agents/components/agent-operators.tsx +164 -0
  27. package/blocks/agents/components/agent-run-detail.tsx +20 -3
  28. package/blocks/agents/components/agent-runs.tsx +3 -3
  29. package/blocks/agents/components/agent-skills-panel.tsx +7 -7
  30. package/blocks/agents/components/agent-test-history.tsx +121 -0
  31. package/blocks/agents/components/agents-screen.tsx +53 -11
  32. package/blocks/agents/components/assistant-sessions.tsx +150 -0
  33. package/blocks/agents/components/duplicate-agent-button.tsx +42 -0
  34. package/blocks/agents/components/from-template-button.tsx +65 -0
  35. package/blocks/agents/components/knowledge-browser.tsx +107 -0
  36. package/blocks/agents/components/knowledge-detail.tsx +156 -0
  37. package/blocks/agents/components/knowledge-form.tsx +69 -0
  38. package/blocks/agents/components/name-dialog.tsx +32 -0
  39. package/blocks/agents/components/receptionist-button.tsx +46 -0
  40. package/blocks/agents/components/save-as-template-button.tsx +32 -0
  41. package/blocks/agents/components/skill-editor.tsx +147 -0
  42. package/blocks/agents/components/skill-library.tsx +111 -0
  43. package/blocks/agents/lib/agent-types.ts +7 -1
  44. package/blocks/agents/lib/facts.tsx +13 -0
  45. package/blocks/agents/lib/knowledge-utils.ts +49 -0
  46. package/blocks/agents/lib/load-more.tsx +141 -0
  47. package/blocks/agents/lib/skill-utils.ts +91 -0
  48. package/blocks/agents/recipes/create-agent-and-attach-skill.ts +1 -1
  49. package/blocks/analytics/components/analytics-screen.tsx +16 -3
  50. package/blocks/analytics/components/kpi-tiles.tsx +1 -1
  51. package/blocks/analytics/components/report-builder.tsx +15 -2
  52. package/blocks/appointments/README.md +6 -0
  53. package/blocks/appointments/block.json +27 -0
  54. package/blocks/appointments/components/booking-page.tsx +2 -2
  55. package/blocks/appointments/components/meeting-contact-links.tsx +49 -0
  56. package/blocks/appointments/components/meeting-detail.tsx +2 -2
  57. package/blocks/appointments/components/meeting-list.tsx +29 -13
  58. package/blocks/appointments/components/record-meetings-tab.tsx +92 -0
  59. package/blocks/campaigns/README.md +1 -1
  60. package/blocks/campaigns/block.json +34 -1
  61. package/blocks/campaigns/components/campaign-assets.tsx +1 -1
  62. package/blocks/campaigns/components/campaign-launch-step.tsx +16 -11
  63. package/blocks/campaigns/components/campaign-links.tsx +180 -0
  64. package/blocks/campaigns/components/campaign-metrics.tsx +1 -1
  65. package/blocks/campaigns/components/campaign-wizard.tsx +10 -5
  66. package/blocks/campaigns/components/icp-detail.tsx +11 -2
  67. package/blocks/campaigns/components/icp-editor.tsx +8 -3
  68. package/blocks/campaigns/components/persona-detail.tsx +11 -2
  69. package/blocks/campaigns/components/persona-editor.tsx +6 -1
  70. package/blocks/campaigns/lib/campaigns-utils.ts +4 -4
  71. package/blocks/coach/components/call-scorecard.tsx +7 -7
  72. package/blocks/company-intelligence/README.md +132 -0
  73. package/blocks/company-intelligence/block.json +318 -0
  74. package/blocks/company-intelligence/components/company-intelligence-screen.tsx +114 -0
  75. package/blocks/company-intelligence/components/company-intelligence-tab.tsx +88 -0
  76. package/blocks/company-intelligence/components/company-profile.tsx +68 -0
  77. package/blocks/company-intelligence/components/intelligence-sources.tsx +63 -0
  78. package/blocks/company-intelligence/components/report-detail.tsx +189 -0
  79. package/blocks/company-intelligence/components/research-reports.tsx +136 -0
  80. package/blocks/company-intelligence/components/research-run.tsx +165 -0
  81. package/blocks/company-intelligence/components/source-detail.tsx +117 -0
  82. package/blocks/company-intelligence/components/source-view.tsx +274 -0
  83. package/blocks/company-intelligence/components/wiki-document-detail.tsx +116 -0
  84. package/blocks/company-intelligence/components/wiki-documents.tsx +66 -0
  85. package/blocks/company-intelligence/hooks/use-intelligence.ts +173 -0
  86. package/blocks/company-intelligence/lib/intelligence-types.ts +230 -0
  87. package/blocks/company-intelligence/lib/safe-markdown.tsx +150 -0
  88. package/blocks/company-intelligence/recipes/read-competitors-and-news.ts +33 -0
  89. package/blocks/company-intelligence/recipes/research-your-website.ts +43 -0
  90. package/blocks/company-intelligence/recipes/write-the-research-reports.ts +54 -0
  91. package/blocks/copilot/components/copilot-memory.tsx +6 -2
  92. package/blocks/copilot/components/copilot-panel.tsx +1 -1
  93. package/blocks/copilot/components/copilot-team-chat.tsx +6 -1
  94. package/blocks/crm/README.md +25 -0
  95. package/blocks/crm/block.json +257 -9
  96. package/blocks/crm/components/bulk-update.tsx +119 -0
  97. package/blocks/crm/components/companies-screen.tsx +23 -9
  98. package/blocks/crm/components/company-detail.tsx +2 -2
  99. package/blocks/crm/components/contact-detail.tsx +4 -4
  100. package/blocks/crm/components/contact-documents-tab.tsx +144 -0
  101. package/blocks/crm/components/contact-insights-tab.tsx +118 -0
  102. package/blocks/crm/components/contact-lookup-link.tsx +85 -0
  103. package/blocks/crm/components/contact-row-actions.tsx +43 -0
  104. package/blocks/crm/components/contact-tag-chips.tsx +113 -0
  105. package/blocks/crm/components/contacts-screen.tsx +77 -18
  106. package/blocks/crm/components/dedupe-review.tsx +6 -1
  107. package/blocks/crm/components/import-wizard.tsx +3 -7
  108. package/blocks/crm/components/list-select.tsx +20 -0
  109. package/blocks/crm/components/owner-assign.tsx +132 -0
  110. package/blocks/crm/components/record-engagement-tab.tsx +103 -0
  111. package/blocks/crm/components/record-form.tsx +1 -1
  112. package/blocks/crm/components/record-open-links.tsx +79 -0
  113. package/blocks/crm/components/tag-assign.tsx +112 -0
  114. package/blocks/crm/components/tag-manager.tsx +178 -0
  115. package/blocks/crm/components/tasks-screen.tsx +35 -15
  116. package/blocks/crm/components/unlock-info-button.tsx +82 -0
  117. package/blocks/crm/components/verify-email-button.tsx +93 -0
  118. package/blocks/crm/hooks/use-all-lists.ts +18 -0
  119. package/blocks/crm/hooks/use-contact-tags.ts +29 -0
  120. package/blocks/crm/hooks/use-page-query.ts +3 -1
  121. package/blocks/crm/lib/crm-types.ts +14 -0
  122. package/blocks/crm/lib/read-lists.ts +16 -0
  123. package/blocks/crm/lib/record-actions.ts +102 -0
  124. package/blocks/deals/README.md +25 -6
  125. package/blocks/deals/block.json +168 -2
  126. package/blocks/deals/components/close-deal-dialog.tsx +169 -0
  127. package/blocks/deals/components/create-deal-button.tsx +109 -0
  128. package/blocks/deals/components/deal-contacts-editor.tsx +134 -0
  129. package/blocks/deals/components/deal-detail.tsx +7 -5
  130. package/blocks/deals/components/deal-filters.tsx +65 -0
  131. package/blocks/deals/components/deal-line-items.tsx +120 -0
  132. package/blocks/deals/components/deal-notes-tab.tsx +97 -0
  133. package/blocks/deals/components/deal-related.tsx +30 -9
  134. package/blocks/deals/components/deal-tasks-tab.tsx +88 -0
  135. package/blocks/deals/components/deals-screen.tsx +57 -22
  136. package/blocks/deals/components/forecast-view.tsx +4 -4
  137. package/blocks/deals/components/pipeline-board.tsx +8 -6
  138. package/blocks/deals/components/pipeline-editor.tsx +132 -0
  139. package/blocks/deals/components/record-deals-tab.tsx +62 -0
  140. package/blocks/deals/components/stage-editor.tsx +1 -1
  141. package/blocks/deals/hooks/use-pipeline-deals.ts +17 -4
  142. package/blocks/deals/lib/deal-extras.ts +156 -0
  143. package/blocks/dialer/README.md +14 -5
  144. package/blocks/dialer/block.json +17 -2
  145. package/blocks/dialer/components/call-contact-button.tsx +26 -9
  146. package/blocks/dialer/components/call-log-screen.tsx +10 -2
  147. package/blocks/dialer/components/call-log.tsx +16 -4
  148. package/blocks/dialer/components/call-queue.tsx +3 -3
  149. package/blocks/dialer/components/dialer-screen.tsx +69 -27
  150. package/blocks/dialer/components/disposition-panel.tsx +1 -1
  151. package/blocks/dialer/components/record-calls-tab.tsx +101 -0
  152. package/blocks/dialer/components/session-start-form.tsx +58 -11
  153. package/blocks/dialer/components/softphone.tsx +1 -1
  154. package/blocks/documents/README.md +86 -0
  155. package/blocks/documents/block.json +378 -0
  156. package/blocks/documents/components/account-bar.tsx +48 -0
  157. package/blocks/documents/components/correspondence-form.tsx +95 -0
  158. package/blocks/documents/components/correspondence-import.tsx +106 -0
  159. package/blocks/documents/components/correspondence-panel.tsx +191 -0
  160. package/blocks/documents/components/documents-screen.tsx +76 -0
  161. package/blocks/documents/components/library-document-detail.tsx +175 -0
  162. package/blocks/documents/components/library-document-form.tsx +105 -0
  163. package/blocks/documents/components/library-folder-form.tsx +74 -0
  164. package/blocks/documents/components/library-panel.tsx +235 -0
  165. package/blocks/documents/components/library-upload.tsx +160 -0
  166. package/blocks/documents/components/question-row.tsx +130 -0
  167. package/blocks/documents/components/questionnaire-detail.tsx +197 -0
  168. package/blocks/documents/components/questionnaires-panel.tsx +173 -0
  169. package/blocks/documents/components/record-documents-tab.tsx +109 -0
  170. package/blocks/documents/lib/documents-types.ts +252 -0
  171. package/blocks/documents/lib/download.ts +64 -0
  172. package/blocks/documents/recipes/follow-a-questionnaire.ts +26 -0
  173. package/blocks/documents/recipes/log-account-correspondence.ts +27 -0
  174. package/blocks/documents/recipes/organize-the-library.ts +25 -0
  175. package/blocks/email-signatures/README.md +123 -0
  176. package/blocks/email-signatures/block.json +341 -0
  177. package/blocks/email-signatures/components/email-signatures-screen.tsx +166 -0
  178. package/blocks/email-signatures/components/signature-assign-template.tsx +119 -0
  179. package/blocks/email-signatures/components/signature-block-editor.tsx +87 -0
  180. package/blocks/email-signatures/components/signature-campaign-form.tsx +165 -0
  181. package/blocks/email-signatures/components/signature-campaigns.tsx +75 -0
  182. package/blocks/email-signatures/components/signature-identity-form.tsx +131 -0
  183. package/blocks/email-signatures/components/signature-mailboxes.tsx +195 -0
  184. package/blocks/email-signatures/components/signature-policy.tsx +130 -0
  185. package/blocks/email-signatures/components/signature-preview.tsx +119 -0
  186. package/blocks/email-signatures/components/signature-report.tsx +77 -0
  187. package/blocks/email-signatures/components/signature-template-details.tsx +112 -0
  188. package/blocks/email-signatures/components/signature-template-form.tsx +109 -0
  189. package/blocks/email-signatures/hooks/use-signatures-data.ts +93 -0
  190. package/blocks/email-signatures/lib/signatures-types.ts +392 -0
  191. package/blocks/email-signatures/recipes/assign-a-signature-to-a-new-hire.ts +32 -0
  192. package/blocks/email-signatures/recipes/create-a-template-and-make-it-default.ts +35 -0
  193. package/blocks/email-signatures/recipes/signature-engagement-report.ts +16 -0
  194. package/blocks/enrichment/README.md +38 -10
  195. package/blocks/enrichment/block.json +164 -12
  196. package/blocks/enrichment/components/auto-enrichment-configs.tsx +134 -0
  197. package/blocks/enrichment/components/auto-enrichment-settings.tsx +82 -0
  198. package/blocks/enrichment/components/bulk-enrich-panel.tsx +79 -30
  199. package/blocks/enrichment/components/email-verify-badge.tsx +3 -3
  200. package/blocks/enrichment/components/enrich-button.tsx +1 -1
  201. package/blocks/enrichment/components/enrichment-activity.tsx +93 -0
  202. package/blocks/enrichment/components/enrichment-job-detail.tsx +18 -0
  203. package/blocks/enrichment/components/enrichment-screen.tsx +103 -19
  204. package/blocks/enrichment/components/list-pipelines.tsx +97 -0
  205. package/blocks/enrichment/components/pipeline-detail.tsx +214 -0
  206. package/blocks/enrichment/components/pipeline-editor.tsx +144 -0
  207. package/blocks/enrichment/components/pipeline-templates.tsx +90 -0
  208. package/blocks/enrichment/components/waterfall-config.tsx +27 -7
  209. package/blocks/enrichment/lib/enrichment-types.ts +51 -0
  210. package/blocks/enrichment/lib/pipeline-types.ts +234 -0
  211. package/blocks/enrichment/recipes/bulk-enrich-and-poll.ts +15 -4
  212. package/blocks/forms/README.md +10 -0
  213. package/blocks/forms/block.json +107 -0
  214. package/blocks/forms/components/form-activity.tsx +71 -0
  215. package/blocks/forms/components/form-backfill.tsx +108 -0
  216. package/blocks/forms/components/form-builder.tsx +1 -1
  217. package/blocks/forms/components/form-embed.tsx +1 -1
  218. package/blocks/forms/components/form-groups.tsx +151 -0
  219. package/blocks/forms/components/form-mapping-editor.tsx +6 -9
  220. package/blocks/forms/components/form-route-history.tsx +72 -0
  221. package/blocks/forms/components/form-saved-views.tsx +81 -0
  222. package/blocks/forms/components/forms-screen.tsx +57 -20
  223. package/blocks/forms/components/more-rows.tsx +30 -0
  224. package/blocks/forms/components/submissions-export.tsx +67 -0
  225. package/blocks/forms/components/submissions-table.tsx +15 -6
  226. package/blocks/forms/lib/forms-extra.ts +67 -0
  227. package/blocks/inbox/README.md +45 -4
  228. package/blocks/inbox/block.json +145 -8
  229. package/blocks/inbox/components/blocked-senders.tsx +103 -0
  230. package/blocks/inbox/components/compose-message.tsx +193 -0
  231. package/blocks/inbox/components/inbox-screen.tsx +54 -6
  232. package/blocks/inbox/components/inbox-search.tsx +106 -0
  233. package/blocks/inbox/components/record-conversations-tab.tsx +154 -0
  234. package/blocks/inbox/components/tag-manager.tsx +136 -0
  235. package/blocks/inbox/components/thread-actions.tsx +133 -0
  236. package/blocks/inbox/components/thread-badge.tsx +2 -2
  237. package/blocks/inbox/components/thread-view.tsx +3 -1
  238. package/blocks/inbox/hooks/use-inbox-mailboxes.ts +31 -0
  239. package/blocks/inbox/lib/inbox-manage.ts +227 -0
  240. package/blocks/integrations/README.md +54 -1
  241. package/blocks/integrations/block.json +189 -15
  242. package/blocks/integrations/components/ad-accounts.tsx +82 -0
  243. package/blocks/integrations/components/connection-health.tsx +59 -0
  244. package/blocks/integrations/components/crm-detail.tsx +20 -1
  245. package/blocks/integrations/components/crm-records.tsx +103 -0
  246. package/blocks/integrations/components/field-mappings.tsx +61 -0
  247. package/blocks/integrations/components/integration-list.tsx +4 -4
  248. package/blocks/integrations/components/integrations-screen.tsx +20 -3
  249. package/blocks/integrations/components/migration-panel.tsx +133 -0
  250. package/blocks/integrations/components/sugarcrm-connect.tsx +95 -0
  251. package/blocks/integrations/components/sync-status.tsx +6 -6
  252. package/blocks/integrations/components/sync-triggers.tsx +134 -0
  253. package/blocks/integrations/components/webhook-detail.tsx +26 -7
  254. package/blocks/integrations/components/webhook-manager.tsx +30 -17
  255. package/blocks/integrations/components/workspace-tools.tsx +127 -0
  256. package/blocks/integrations/lib/crm-utils.ts +39 -0
  257. package/blocks/integrations/lib/facts.tsx +13 -0
  258. package/blocks/integrations/lib/integrations-utils.ts +5 -0
  259. package/blocks/integrations/lib/load-more.tsx +141 -0
  260. package/blocks/intent/components/account-intent-score.tsx +5 -5
  261. package/blocks/intent/components/intent-feed.tsx +8 -8
  262. package/blocks/intent/components/intent-keyword-manager.tsx +8 -8
  263. package/blocks/intent/lib/intent-utils.ts +4 -4
  264. package/blocks/lifecycle/components/account-related.tsx +8 -1
  265. package/blocks/lifecycle/components/churn-list.tsx +5 -2
  266. package/blocks/lifecycle/components/customer-table.tsx +1 -1
  267. package/blocks/lists/README.md +7 -1
  268. package/blocks/lists/block.json +31 -3
  269. package/blocks/lists/components/add-company-people-to-list-button.tsx +73 -0
  270. package/blocks/lists/components/add-to-list-button.tsx +17 -7
  271. package/blocks/lists/components/list-picker.tsx +13 -3
  272. package/blocks/lists/components/list-table.tsx +1 -1
  273. package/blocks/lists/components/lists-screen.tsx +4 -2
  274. package/blocks/lists/components/record-lists-tab.tsx +99 -0
  275. package/blocks/lists/components/suppression-manager.tsx +27 -6
  276. package/blocks/lists/components/suppressions-screen.tsx +21 -12
  277. package/blocks/mailboxes/block.json +4 -0
  278. package/blocks/mailboxes/components/connect-mailbox.tsx +9 -8
  279. package/blocks/mailboxes/components/domain-detail.tsx +10 -4
  280. package/blocks/mailboxes/components/domain-purchase.tsx +14 -11
  281. package/blocks/mailboxes/components/mailbox-detail.tsx +3 -2
  282. package/blocks/mailboxes/components/mailbox-list.tsx +8 -3
  283. package/blocks/mailboxes/components/mailboxes-screen.tsx +8 -3
  284. package/blocks/mailboxes/components/warmup-health.tsx +20 -20
  285. package/blocks/mailboxes/lib/mailboxes-utils.ts +4 -4
  286. package/blocks/mailboxes/lib/use-provider-domains.ts +23 -0
  287. package/blocks/newsletter/README.md +12 -0
  288. package/blocks/newsletter/block.json +117 -0
  289. package/blocks/newsletter/components/issue-scheduler.tsx +2 -2
  290. package/blocks/newsletter/components/issue-versions.tsx +93 -0
  291. package/blocks/newsletter/components/more-rows.tsx +30 -0
  292. package/blocks/newsletter/components/newsletter-editor.tsx +1 -1
  293. package/blocks/newsletter/components/newsletter-list-syncs.tsx +121 -0
  294. package/blocks/newsletter/components/newsletter-screen.tsx +38 -13
  295. package/blocks/newsletter/components/newsletter-settings.tsx +211 -0
  296. package/blocks/newsletter/components/newsletter-stats.tsx +2 -2
  297. package/blocks/newsletter/components/newsletter-templates.tsx +133 -0
  298. package/blocks/newsletter/components/subscriber-table.tsx +5 -7
  299. package/blocks/newsletter/components/subscriber-timeline.tsx +65 -0
  300. package/blocks/newsletter/lib/newsletter-extra.ts +60 -0
  301. package/blocks/nurture/components/nurture-builder.tsx +10 -2
  302. package/blocks/nurture/components/nurture-enroll.tsx +6 -7
  303. package/blocks/nurture/components/nurture-form.tsx +5 -8
  304. package/blocks/nurture/components/nurture-screen.tsx +16 -5
  305. package/blocks/nurture/components/nurture-stats.tsx +5 -4
  306. package/blocks/objects/README.md +1 -1
  307. package/blocks/objects/block.json +13 -5
  308. package/blocks/objects/components/attribute-field-input.tsx +14 -1
  309. package/blocks/objects/components/object-record-detail.tsx +8 -1
  310. package/blocks/objects/components/object-schema-editor.tsx +1 -1
  311. package/blocks/objects/components/record-roles-panel.tsx +15 -5
  312. package/blocks/pages/README.md +14 -0
  313. package/blocks/pages/block.json +123 -2
  314. package/blocks/pages/components/more-rows.tsx +30 -0
  315. package/blocks/pages/components/page-ai-tools.tsx +196 -0
  316. package/blocks/pages/components/page-analytics.tsx +176 -0
  317. package/blocks/pages/components/page-clone.tsx +99 -0
  318. package/blocks/pages/components/page-domains.tsx +167 -0
  319. package/blocks/pages/components/page-editor.tsx +1 -1
  320. package/blocks/pages/components/page-generation-status.tsx +48 -0
  321. package/blocks/pages/components/page-tracking.tsx +137 -0
  322. package/blocks/pages/components/pages-screen.tsx +57 -16
  323. package/blocks/pages/components/seo-report.tsx +6 -1
  324. package/blocks/pages/hooks/use-landing-page-paths.ts +60 -0
  325. package/blocks/pages/lib/studio.ts +7 -0
  326. package/blocks/phone-numbers/README.md +74 -0
  327. package/blocks/phone-numbers/block.json +262 -0
  328. package/blocks/phone-numbers/components/a2p-registration.tsx +230 -0
  329. package/blocks/phone-numbers/components/assign-number.tsx +104 -0
  330. package/blocks/phone-numbers/components/number-search.tsx +239 -0
  331. package/blocks/phone-numbers/components/number-settings.tsx +134 -0
  332. package/blocks/phone-numbers/components/number-usage.tsx +97 -0
  333. package/blocks/phone-numbers/components/phone-number-detail.tsx +84 -0
  334. package/blocks/phone-numbers/components/phone-number-list.tsx +110 -0
  335. package/blocks/phone-numbers/components/phone-numbers-screen.tsx +201 -0
  336. package/blocks/phone-numbers/components/register-owned-number.tsx +98 -0
  337. package/blocks/phone-numbers/components/release-number.tsx +126 -0
  338. package/blocks/phone-numbers/hooks/use-phone-numbers.ts +58 -0
  339. package/blocks/phone-numbers/lib/phone-numbers-utils.ts +202 -0
  340. package/blocks/phone-numbers/recipes/01-search-and-buy-number.ts +49 -0
  341. package/blocks/phone-numbers/recipes/02-assign-number-to-rep.ts +25 -0
  342. package/blocks/phone-numbers/recipes/03-audit-numbers.ts +36 -0
  343. package/blocks/phone-numbers/recipes/04-register-text-messaging.ts +39 -0
  344. package/blocks/pickers/README.md +23 -0
  345. package/blocks/pickers/block.json +103 -0
  346. package/blocks/pickers/components/company-picker.tsx +90 -0
  347. package/blocks/pickers/components/contact-picker.tsx +131 -0
  348. package/blocks/pickers/components/member-picker.tsx +99 -0
  349. package/blocks/pickers/components/search-picker.tsx +98 -0
  350. package/blocks/pickers/hooks/use-current-member.ts +104 -0
  351. package/blocks/pickers/hooks/use-picker-pages.ts +73 -0
  352. package/blocks/pickers/lib/use-debounced.ts +13 -0
  353. package/blocks/programmatic-pages/README.md +82 -0
  354. package/blocks/programmatic-pages/block.json +292 -0
  355. package/blocks/programmatic-pages/components/programmatic-campaign-form.tsx +136 -0
  356. package/blocks/programmatic-pages/components/programmatic-generate.tsx +112 -0
  357. package/blocks/programmatic-pages/components/programmatic-generated-pages.tsx +210 -0
  358. package/blocks/programmatic-pages/components/programmatic-overview.tsx +84 -0
  359. package/blocks/programmatic-pages/components/programmatic-pages-screen.tsx +221 -0
  360. package/blocks/programmatic-pages/components/programmatic-preview.tsx +66 -0
  361. package/blocks/programmatic-pages/components/programmatic-publish.tsx +102 -0
  362. package/blocks/programmatic-pages/components/programmatic-settings.tsx +96 -0
  363. package/blocks/programmatic-pages/components/programmatic-source-fields.tsx +75 -0
  364. package/blocks/programmatic-pages/components/programmatic-source.tsx +106 -0
  365. package/blocks/programmatic-pages/components/programmatic-variables.tsx +84 -0
  366. package/blocks/programmatic-pages/hooks/use-programmatic-workspace.ts +19 -0
  367. package/blocks/programmatic-pages/lib/programmatic-types.ts +330 -0
  368. package/blocks/programmatic-pages/recipes/create-a-programmatic-campaign.ts +23 -0
  369. package/blocks/programmatic-pages/recipes/render-and-follow.ts +21 -0
  370. package/blocks/programmatic-pages/recipes/review-then-publish.ts +17 -0
  371. package/blocks/quotes/README.md +38 -1
  372. package/blocks/quotes/block.json +170 -6
  373. package/blocks/quotes/components/create-quote-from-deal.tsx +48 -0
  374. package/blocks/quotes/components/manual-products.tsx +144 -0
  375. package/blocks/quotes/components/quote-batch-actions.tsx +86 -0
  376. package/blocks/quotes/components/quote-builder.tsx +1 -1
  377. package/blocks/quotes/components/quote-documents.tsx +94 -0
  378. package/blocks/quotes/components/quote-evidence.tsx +95 -0
  379. package/blocks/quotes/components/quote-lifecycle-actions.tsx +146 -0
  380. package/blocks/quotes/components/quote-list.tsx +28 -8
  381. package/blocks/quotes/components/quote-related.tsx +3 -2
  382. package/blocks/quotes/components/quote-settings.tsx +184 -0
  383. package/blocks/quotes/components/quote-templates.tsx +189 -0
  384. package/blocks/quotes/components/quote-viewer.tsx +23 -5
  385. package/blocks/quotes/components/quotes-screen.tsx +15 -5
  386. package/blocks/quotes/components/record-quotes-tab.tsx +90 -0
  387. package/blocks/quotes/lib/quote-admin.ts +264 -0
  388. package/blocks/radar/components/competitor-battle-card.tsx +1 -1
  389. package/blocks/radar/components/radar-overview.tsx +4 -4
  390. package/blocks/radar/components/radar-screen.tsx +2 -2
  391. package/blocks/sequencer/README.md +61 -0
  392. package/blocks/sequencer/block.json +200 -6
  393. package/blocks/sequencer/components/add-to-sequence-button.tsx +82 -0
  394. package/blocks/sequencer/components/enroll-dialog.tsx +2 -2
  395. package/blocks/sequencer/components/enrollment-withdraw.tsx +71 -0
  396. package/blocks/sequencer/components/record-sequences-tab.tsx +126 -0
  397. package/blocks/sequencer/components/sequence-builder.tsx +32 -23
  398. package/blocks/sequencer/components/sequence-campaign-link.tsx +78 -0
  399. package/blocks/sequencer/components/sequence-detail.tsx +10 -2
  400. package/blocks/sequencer/components/sequence-edit-form.tsx +111 -0
  401. package/blocks/sequencer/components/sequence-enrollments.tsx +5 -2
  402. package/blocks/sequencer/components/sequence-list.tsx +1 -1
  403. package/blocks/sequencer/components/sequence-manage-actions.tsx +119 -0
  404. package/blocks/sequencer/components/sequence-senders-panel.tsx +84 -0
  405. package/blocks/sequencer/components/sequence-stats.tsx +8 -8
  406. package/blocks/sequencer/components/sequence-templates.tsx +160 -0
  407. package/blocks/sequencer/components/sequences-screen.tsx +39 -6
  408. package/blocks/sequencer/components/step-ai-assist.tsx +196 -0
  409. package/blocks/sequencer/components/step-editor.tsx +21 -12
  410. package/blocks/sequencer/components/step-templates.tsx +224 -0
  411. package/blocks/sequencer/lib/sequencer-manage.ts +235 -0
  412. package/blocks/sequencer/lib/sequencer-utils.ts +9 -5
  413. package/blocks/signals/README.md +39 -0
  414. package/blocks/signals/block.json +287 -0
  415. package/blocks/signals/components/auto-seed-panel.tsx +111 -0
  416. package/blocks/signals/components/listener-form.tsx +184 -0
  417. package/blocks/signals/components/matched-posts.tsx +195 -0
  418. package/blocks/signals/components/post-engagements.tsx +114 -0
  419. package/blocks/signals/components/record-social-tab.tsx +49 -0
  420. package/blocks/signals/components/social-listeners-screen.tsx +250 -0
  421. package/blocks/signals/components/social-settings.tsx +128 -0
  422. package/blocks/signals/components/source-lists.tsx +83 -0
  423. package/blocks/signals/components/top-engagers.tsx +68 -0
  424. package/blocks/signals/components/x-integration.tsx +129 -0
  425. package/blocks/signals/lib/signals-types.ts +228 -0
  426. package/blocks/signals/recipes/preview-and-create-a-listener.ts +16 -0
  427. package/blocks/signals/recipes/spend-against-caps.ts +14 -0
  428. package/blocks/signals/recipes/triage-matched-posts.ts +18 -0
  429. package/blocks/social-ads/README.md +8 -0
  430. package/blocks/social-ads/block.json +137 -4
  431. package/blocks/social-ads/components/audience-sync-detail.tsx +9 -3
  432. package/blocks/social-ads/components/audience-sync.tsx +6 -2
  433. package/blocks/social-ads/components/campaign-ads.tsx +166 -0
  434. package/blocks/social-ads/components/campaign-detail.tsx +6 -1
  435. package/blocks/social-ads/components/campaign-editor.tsx +134 -0
  436. package/blocks/social-ads/components/creative-concepts.tsx +74 -0
  437. package/blocks/social-ads/components/creative-detail.tsx +6 -1
  438. package/blocks/social-ads/components/creative-gallery.tsx +20 -2
  439. package/blocks/social-ads/components/creative-revisions.tsx +57 -0
  440. package/blocks/social-ads/components/creative-tools.tsx +176 -0
  441. package/blocks/social-ads/components/post-composer.tsx +4 -2
  442. package/blocks/social-ads/components/post-detail.tsx +3 -0
  443. package/blocks/social-ads/components/social-ideas.tsx +64 -0
  444. package/blocks/social-ads/components/social-performance.tsx +80 -0
  445. package/blocks/social-ads/components/social-screen.tsx +33 -6
  446. package/blocks/social-ads/lib/ads-extra.ts +67 -0
  447. package/blocks/surveys/README.md +91 -0
  448. package/blocks/surveys/block.json +299 -0
  449. package/blocks/surveys/components/account-nps.tsx +69 -0
  450. package/blocks/surveys/components/contact-survey-history.tsx +52 -0
  451. package/blocks/surveys/components/org-summary.tsx +82 -0
  452. package/blocks/surveys/components/sending-domains.tsx +113 -0
  453. package/blocks/surveys/components/survey-form.tsx +126 -0
  454. package/blocks/surveys/components/survey-responses.tsx +145 -0
  455. package/blocks/surveys/components/survey-results.tsx +72 -0
  456. package/blocks/surveys/components/survey-send-history.tsx +58 -0
  457. package/blocks/surveys/components/survey-send.tsx +162 -0
  458. package/blocks/surveys/components/survey-triggers.tsx +166 -0
  459. package/blocks/surveys/components/surveys-screen.tsx +234 -0
  460. package/blocks/surveys/lib/surveys-types.ts +228 -0
  461. package/blocks/surveys/recipes/create-an-nps-survey.ts +22 -0
  462. package/blocks/surveys/recipes/send-a-survey-and-follow-it.ts +27 -0
  463. package/blocks/surveys/recipes/survey-score-report.ts +27 -0
  464. package/blocks/visitors/components/snippet-install.tsx +18 -9
  465. package/blocks/visitors/components/traffic-chart.tsx +7 -6
  466. package/blocks/visitors/components/visitor-company-card.tsx +24 -14
  467. package/blocks/visitors/components/visitor-feed.tsx +5 -5
  468. package/blocks/web-analytics/README.md +102 -0
  469. package/blocks/web-analytics/block.json +292 -0
  470. package/blocks/web-analytics/components/acquisition-tab.tsx +154 -0
  471. package/blocks/web-analytics/components/analytics-filters.tsx +161 -0
  472. package/blocks/web-analytics/components/audience-tab.tsx +135 -0
  473. package/blocks/web-analytics/components/conversions-tab.tsx +128 -0
  474. package/blocks/web-analytics/components/engagement-tab.tsx +123 -0
  475. package/blocks/web-analytics/components/overview-tab.tsx +102 -0
  476. package/blocks/web-analytics/components/pages-tab.tsx +148 -0
  477. package/blocks/web-analytics/components/ranked-table.tsx +103 -0
  478. package/blocks/web-analytics/components/realtime-tab.tsx +103 -0
  479. package/blocks/web-analytics/components/report-card.tsx +71 -0
  480. package/blocks/web-analytics/components/web-analytics-screen.tsx +90 -0
  481. package/blocks/web-analytics/hooks/use-report.ts +48 -0
  482. package/blocks/web-analytics/lib/analytics-scope.ts +155 -0
  483. package/blocks/web-analytics/lib/page-path.ts +14 -0
  484. package/blocks/web-analytics/lib/web-analytics-types.ts +187 -0
  485. package/blocks/web-analytics/recipes/best-landing-pages.ts +26 -0
  486. package/blocks/web-analytics/recipes/form-conversion-check.ts +19 -0
  487. package/blocks/web-analytics/recipes/weekly-traffic-report.ts +37 -0
  488. package/blocks/webchat/components/chat-widget-config.tsx +1 -1
  489. package/blocks/webchat/components/conversation-list.tsx +1 -1
  490. package/blocks/workbench/README.md +54 -2
  491. package/blocks/workbench/block.json +234 -5
  492. package/blocks/workbench/components/column-recipe-editor.tsx +1 -1
  493. package/blocks/workbench/components/run-progress.tsx +1 -1
  494. package/blocks/workbench/components/workbench-auto-enrich.tsx +88 -0
  495. package/blocks/workbench/components/workbench-automation.tsx +36 -0
  496. package/blocks/workbench/components/workbench-connections.tsx +136 -0
  497. package/blocks/workbench/components/workbench-crm-import.tsx +91 -0
  498. package/blocks/workbench/components/workbench-datafile-import.tsx +154 -0
  499. package/blocks/workbench/components/workbench-grid.tsx +71 -8
  500. package/blocks/workbench/components/workbench-pipelines.tsx +173 -0
  501. package/blocks/workbench/components/workbench-row-actions.tsx +8 -1
  502. package/blocks/workbench/components/workbench-schedule.tsx +191 -0
  503. package/blocks/workbench/components/workbench-screen.tsx +65 -22
  504. package/blocks/workbench/components/workbench-send-to-sequence.tsx +116 -0
  505. package/blocks/workbench/components/workbench-table-list.tsx +14 -2
  506. package/blocks/workbench/components/workbench-table-settings.tsx +53 -0
  507. package/blocks/workbench/components/workbench-triggers.tsx +178 -0
  508. package/blocks/workbench/hooks/use-connected-crms.ts +29 -0
  509. package/blocks/workbench/lib/api-status.ts +8 -0
  510. package/blocks/workbench/lib/automation-types.ts +257 -0
  511. package/blocks/workflows/components/workflow-editor.tsx +1 -1
  512. package/dist/cli.js +744 -394
  513. package/dist/index.browser.js +1 -1
  514. package/dist/index.browser.js.map +1 -1
  515. package/dist/index.browser.mjs +1 -1
  516. package/dist/index.browser.mjs.map +1 -1
  517. package/dist/index.d.mts +2 -2
  518. package/dist/index.d.ts +2 -2
  519. package/dist/index.js +1 -1
  520. package/dist/index.js.map +1 -1
  521. package/dist/index.mjs +1 -1
  522. package/dist/index.mjs.map +1 -1
  523. package/dist/react.browser.js +1 -1
  524. package/dist/react.browser.js.map +1 -1
  525. package/dist/react.browser.mjs +1 -1
  526. package/dist/react.browser.mjs.map +1 -1
  527. package/dist/react.d.mts +2 -2
  528. package/dist/react.d.ts +2 -2
  529. package/dist/react.js +1 -1
  530. package/dist/react.js.map +1 -1
  531. package/dist/react.mjs +1 -1
  532. package/dist/react.mjs.map +1 -1
  533. package/dist/types/blocks/auth.d.ts +45 -0
  534. package/dist/types/blocks/brand.d.ts +11 -2
  535. package/dist/types/blocks/create.d.ts +11 -4
  536. package/dist/types/blocks/doctor.d.ts +1 -0
  537. package/dist/types/blocks/flows.d.ts +7 -1
  538. package/dist/types/blocks/orgBrand.d.ts +34 -0
  539. package/dist/types/cli.d.ts +3 -0
  540. package/dist/types/version.d.ts +2 -2
  541. package/docs/api/desk.d.ts +2 -2
  542. package/docs/api/desk.md +3 -3
  543. package/docs/api/forms.md +1 -1
  544. package/package.json +1 -1
  545. package/stacks/6sense/pages/companies.tsx.tmpl +21 -0
  546. package/stacks/6sense/pages/contacts.tsx.tmpl +21 -0
  547. package/stacks/6sense/pages/tasks.tsx.tmpl +19 -0
  548. package/stacks/6sense.json +37 -4
  549. package/stacks/apollo/pages/calls.tsx.tmpl +23 -0
  550. package/stacks/apollo/pages/campaigns.tsx.tmpl +27 -0
  551. package/stacks/apollo/pages/companies.tsx.tmpl +19 -36
  552. package/stacks/apollo/pages/contacts.tsx.tmpl +35 -95
  553. package/stacks/apollo/pages/deals.tsx.tmpl +17 -0
  554. package/stacks/apollo/pages/inbox-contact.tsx.tmpl +13 -0
  555. package/stacks/apollo/pages/lists.tsx.tmpl +24 -0
  556. package/stacks/apollo/pages/meetings.tsx.tmpl +13 -0
  557. package/stacks/apollo/pages/sequences.tsx.tmpl +18 -0
  558. package/stacks/apollo/pages/tasks.tsx.tmpl +20 -0
  559. package/stacks/apollo.json +68 -9
  560. package/stacks/calendly/pages/companies.tsx.tmpl +19 -0
  561. package/stacks/calendly/pages/contacts.tsx.tmpl +21 -0
  562. package/stacks/calendly/pages/meetings.tsx.tmpl +13 -0
  563. package/stacks/calendly/pages/tasks.tsx.tmpl +19 -0
  564. package/stacks/calendly.json +8 -4
  565. package/stacks/clay/pages/companies.tsx.tmpl +17 -1
  566. package/stacks/clay/pages/contacts.tsx.tmpl +14 -0
  567. package/stacks/clay/pages/lists.tsx.tmpl +24 -0
  568. package/stacks/clay/pages/tasks.tsx.tmpl +19 -0
  569. package/stacks/clay.json +16 -3
  570. package/stacks/gong/pages/calls.tsx.tmpl +23 -0
  571. package/stacks/gong/pages/companies.tsx.tmpl +22 -0
  572. package/stacks/gong/pages/contacts.tsx.tmpl +34 -0
  573. package/stacks/gong/pages/lists.tsx.tmpl +12 -0
  574. package/stacks/gong/pages/meetings.tsx.tmpl +13 -0
  575. package/stacks/gong/pages/tasks.tsx.tmpl +19 -0
  576. package/stacks/gong.json +23 -6
  577. package/stacks/hootsuite/pages/companies.tsx.tmpl +22 -0
  578. package/stacks/hootsuite/pages/contacts.tsx.tmpl +30 -0
  579. package/stacks/hootsuite/pages/lists.tsx.tmpl +12 -0
  580. package/stacks/hootsuite/pages/tasks.tsx.tmpl +19 -0
  581. package/stacks/hootsuite.json +19 -4
  582. package/stacks/hubspot/pages/campaigns.tsx.tmpl +30 -0
  583. package/stacks/hubspot/pages/companies.tsx.tmpl +16 -35
  584. package/stacks/hubspot/pages/contacts.tsx.tmpl +35 -95
  585. package/stacks/hubspot/pages/deals.tsx.tmpl +14 -1
  586. package/stacks/hubspot/pages/forms.tsx.tmpl +36 -0
  587. package/stacks/hubspot/pages/inbox.tsx.tmpl +12 -1
  588. package/stacks/hubspot/pages/lifecycle.tsx.tmpl +23 -0
  589. package/stacks/hubspot/pages/lists.tsx.tmpl +12 -0
  590. package/stacks/hubspot/pages/meetings.tsx.tmpl +13 -0
  591. package/stacks/hubspot/pages/sequences.tsx.tmpl +18 -0
  592. package/stacks/hubspot/pages/tasks.tsx.tmpl +20 -0
  593. package/stacks/hubspot/pages/web-analytics.tsx.tmpl +14 -0
  594. package/stacks/hubspot.json +66 -7
  595. package/stacks/intercom/pages/companies.tsx.tmpl +19 -0
  596. package/stacks/intercom/pages/contacts.tsx.tmpl +21 -0
  597. package/stacks/intercom/pages/inbox-contact.tsx.tmpl +13 -0
  598. package/stacks/intercom/pages/tasks.tsx.tmpl +19 -0
  599. package/stacks/intercom.json +18 -4
  600. package/stacks/mailchimp/pages/companies.tsx.tmpl +22 -0
  601. package/stacks/mailchimp/pages/contacts.tsx.tmpl +30 -0
  602. package/stacks/mailchimp/pages/forms.tsx.tmpl +36 -0
  603. package/stacks/mailchimp/pages/lists.tsx.tmpl +12 -0
  604. package/stacks/mailchimp/pages/tasks.tsx.tmpl +19 -0
  605. package/stacks/mailchimp.json +22 -6
  606. package/stacks/outreach/pages/calls.tsx.tmpl +23 -0
  607. package/stacks/outreach/pages/campaigns.tsx.tmpl +27 -0
  608. package/stacks/outreach/pages/companies.tsx.tmpl +22 -0
  609. package/stacks/outreach/pages/contacts.tsx.tmpl +29 -66
  610. package/stacks/outreach/pages/inbox-contact.tsx.tmpl +13 -0
  611. package/stacks/outreach/pages/lists.tsx.tmpl +12 -0
  612. package/stacks/outreach/pages/meetings.tsx.tmpl +13 -0
  613. package/stacks/outreach/pages/sequences.tsx.tmpl +18 -0
  614. package/stacks/outreach/pages/tasks.tsx.tmpl +19 -0
  615. package/stacks/outreach.json +38 -9
  616. package/stacks/pipedrive/pages/companies.tsx.tmpl +11 -35
  617. package/stacks/pipedrive/pages/contacts.tsx.tmpl +17 -35
  618. package/stacks/pipedrive/pages/deals.tsx.tmpl +10 -1
  619. package/stacks/pipedrive/pages/inbox.tsx.tmpl +12 -1
  620. package/stacks/pipedrive/pages/meetings.tsx.tmpl +13 -0
  621. package/stacks/pipedrive/pages/tasks.tsx.tmpl +20 -0
  622. package/stacks/pipedrive.json +14 -2
  623. package/stacks/salesforce/pages/companies.tsx.tmpl +16 -35
  624. package/stacks/salesforce/pages/contacts.tsx.tmpl +26 -35
  625. package/stacks/salesforce/pages/deals.tsx.tmpl +14 -1
  626. package/stacks/salesforce/pages/lifecycle.tsx.tmpl +23 -0
  627. package/stacks/salesforce/pages/lists.tsx.tmpl +12 -0
  628. package/stacks/salesforce/pages/tasks.tsx.tmpl +20 -0
  629. package/stacks/salesforce.json +17 -3
  630. package/stacks/zoominfo/pages/companies.tsx.tmpl +17 -1
  631. package/stacks/zoominfo/pages/contacts.tsx.tmpl +16 -0
  632. package/stacks/zoominfo/pages/lists.tsx.tmpl +24 -0
  633. package/stacks/zoominfo/pages/tasks.tsx.tmpl +19 -0
  634. package/stacks/zoominfo.json +36 -3
  635. package/styles/styles.css +1 -1
  636. package/templates/auth/auth-route.ts.tmpl +16 -0
  637. package/templates/auth/g8.auth.anonymous.ts.tmpl +15 -0
  638. package/templates/auth/g8.auth.basic.ts.tmpl +17 -0
  639. package/templates/auth/g8.auth.jwt.ts.tmpl +23 -0
  640. package/templates/auth/g8.auth.password.ts.tmpl +18 -0
  641. package/templates/auth/g8.auth.session.ts.tmpl +23 -0
  642. package/templates/auth/middleware.ts.tmpl +14 -0
  643. package/templates/next-app/README.md.tmpl +5 -0
  644. package/templates/next-app/app/globals.css.tmpl +349 -64
  645. package/templates/next-app/components/app-shell.tsx.tmpl +6 -0
  646. package/templates/next-app/components/shell/quick-jump.tsx.tmpl +4 -0
@@ -8,31 +8,64 @@
8
8
  "email verification chip with a one-click verify",
9
9
  "bulk enrichment with a free preflight, credit estimate confirmation, polled progress and cancel",
10
10
  "waterfall pipeline manager with provider order and credential readiness",
11
- "finished EnrichmentScreen page"
11
+ "finished EnrichmentScreen page",
12
+ "list pipelines: templates, build, edit, price (free estimate), run behind a confirm, watch, stop, on/off, delete, run history",
13
+ "automatic enrichment of a list's new records and the workspace-wide switch and merge rule, each confirmed with the real billing effect",
14
+ "pause and resume a running enrichment job; enrichment activity analytics (totals, success rate, trends, fields filled)"
12
15
  ],
13
16
  "dependsOn": [
14
- "lists"
17
+ "lists",
18
+ "pickers"
15
19
  ],
16
20
  "operations": [
17
21
  "cancel_enrichment_job_enrichment_jobs__job_id__cancel_post",
22
+ "cancel_list_pipeline_run_enrichment_lists__list_id__pipelines__pipeline_id__cancel_post",
23
+ "create_auto_enrichment_config_enrichment_auto_enrichment_configs_post",
18
24
  "create_default_waterfall_config_enrichment_waterfall_configs_post",
19
25
  "create_list_lists_post",
26
+ "create_list_pipeline_enrichment_lists__list_id__pipelines_post",
27
+ "create_list_pipeline_from_template_enrichment_lists__list_id__pipelines_from_template_post",
28
+ "delete_auto_enrichment_config_enrichment_auto_enrichment_configs__config_id__delete",
20
29
  "delete_contact_contacts__contact_id__delete",
30
+ "delete_list_pipeline_enrichment_lists__list_id__pipelines__pipeline_id__delete",
21
31
  "delete_waterfall_config_enrichment_waterfall_configs__column_id__delete",
32
+ "estimate_list_pipeline_enrichment_lists__list_id__pipelines__pipeline_id__estimate_post",
33
+ "get_auto_enrichment_config_enrichment_auto_enrichment_configs__config_id__get",
34
+ "get_auto_enrichment_settings_enrichment_auto_enrichment_settings_get",
22
35
  "get_company_companies__company_id__get",
23
36
  "get_contact_contacts__contact_id__get",
37
+ "get_enrichment_daily_activity_enrichment_analytics_daily_activity_get",
38
+ "get_enrichment_field_distribution_enrichment_analytics_field_distribution_get",
24
39
  "get_enrichment_job_enrichment_jobs__job_id__get",
40
+ "get_enrichment_metrics_enrichment_analytics_metrics_get",
41
+ "get_enrichment_trends_enrichment_analytics_trends_get",
42
+ "get_pipeline_run_enrichment_lists_pipeline_runs__run_id__get",
43
+ "list_active_enrichment_jobs_enrichment_active_jobs_get",
44
+ "list_auto_enrichment_configs_enrichment_auto_enrichment_configs_get",
45
+ "list_companies_companies_get",
25
46
  "list_contact_fields_fields_get",
26
47
  "list_contacts_contacts_get",
27
48
  "list_enrichment_providers_enrichment_providers_get",
49
+ "list_list_pipeline_runs_enrichment_lists__list_id__pipelines__pipeline_id__runs_get",
50
+ "list_list_pipelines_enrichment_lists__list_id__pipelines_get",
28
51
  "list_lists_lists_get",
52
+ "list_pipeline_step_options_enrichment_lists__list_id__pipeline_step_options_get",
53
+ "list_pipeline_templates_enrichment_lists_pipeline_templates_get",
29
54
  "list_waterfall_configs_enrichment_waterfall_configs_get",
30
55
  "lookup_company_enrichment_lookup_company_post",
31
56
  "lookup_person_enrichment_lookup_person_post",
57
+ "pause_enrichment_job_enrichment_jobs__job_id__pause_post",
32
58
  "preflight_enrichment_enrichment_preflight_post",
59
+ "resume_enrichment_job_enrichment_jobs__job_id__resume_post",
60
+ "run_list_pipeline_enrichment_lists__list_id__pipelines__pipeline_id__runs_post",
61
+ "run_waterfall_pipeline_enrichment_waterfall_enrich_post",
62
+ "set_pipeline_enabled_enrichment_lists__list_id__pipelines__pipeline_id__enabled_post",
33
63
  "start_enrichment_enrichment_enrich_post",
64
+ "update_auto_enrichment_config_enrichment_auto_enrichment_configs__config_id__patch",
65
+ "update_auto_enrichment_settings_enrichment_auto_enrichment_settings__entity_type__put",
34
66
  "update_company_companies__company_id__patch",
35
67
  "update_contact_contacts__contact_id__patch",
68
+ "update_list_pipeline_enrichment_lists__list_id__pipelines__pipeline_id__put",
36
69
  "verify_email_enrichment_verify_email_post"
37
70
  ],
38
71
  "components": [
@@ -68,11 +101,13 @@
68
101
  {
69
102
  "name": "BulkEnrichPanel",
70
103
  "file": "components/bulk-enrich-panel.tsx",
71
- "purpose": "Fill a field for many contacts of a list: free preflight, credit estimate in ConfirmSpendDialog, start the job, poll it with useJobPoll, cancel. With no props it is a whole page (pick a list, tick contacts).",
104
+ "purpose": "Fill a field for many contacts of a list: free preflight, credit estimate in ConfirmSpendDialog, create or reuse the field's pipeline and run it, poll it with useJobPoll, cancel. With no props it is a whole page (pick a list, tick contacts).",
72
105
  "operations": [
73
106
  "list_enrichment_providers_enrichment_providers_get",
107
+ "list_waterfall_configs_enrichment_waterfall_configs_get",
74
108
  "preflight_enrichment_enrichment_preflight_post",
75
- "start_enrichment_enrichment_enrich_post",
109
+ "create_default_waterfall_config_enrichment_waterfall_configs_post",
110
+ "run_waterfall_pipeline_enrichment_waterfall_enrich_post",
76
111
  "get_enrichment_job_enrichment_jobs__job_id__get",
77
112
  "cancel_enrichment_job_enrichment_jobs__job_id__cancel_post",
78
113
  "list_lists_lists_get",
@@ -107,22 +142,135 @@
107
142
  {
108
143
  "name": "EnrichmentScreen",
109
144
  "file": "components/enrichment-screen.tsx",
110
- "purpose": "Finished enrichment page: enrich a list, one-off lookups and email verification, pipelines and the provider catalog.",
111
- "operations": [],
112
- "tiers": []
145
+ "purpose": "Finished enrichment page: enrich a list, one-off lookups and email verification, pipelines, list pipelines, auto-enrichment, jobs, activity and the provider catalog.",
146
+ "operations": [
147
+ "list_contacts_contacts_get",
148
+ "list_companies_companies_get",
149
+ "list_active_enrichment_jobs_enrichment_active_jobs_get"
150
+ ],
151
+ "tiers": [
152
+ "read"
153
+ ]
113
154
  },
114
155
  {
115
156
  "name": "EnrichmentJobDetail",
116
157
  "file": "components/enrichment-job-detail.tsx",
117
- "purpose": "One bulk enrichment job: live progress, counts, credits, warnings, provider errors and cancel.",
158
+ "purpose": "One bulk enrichment job: live progress, counts, credits, warnings, provider errors, cancel, pause and resume (resume is confirmed).",
118
159
  "operations": [
119
160
  "cancel_enrichment_job_enrichment_jobs__job_id__cancel_post",
120
- "get_enrichment_job_enrichment_jobs__job_id__get"
161
+ "get_enrichment_job_enrichment_jobs__job_id__get",
162
+ "pause_enrichment_job_enrichment_jobs__job_id__pause_post",
163
+ "resume_enrichment_job_enrichment_jobs__job_id__resume_post"
164
+ ],
165
+ "tiers": [
166
+ "read",
167
+ "write",
168
+ "billable"
169
+ ]
170
+ },
171
+ {
172
+ "name": "ListPipelines",
173
+ "file": "components/list-pipelines.tsx",
174
+ "purpose": "The pipelines of one list with the open one beside them: templates, new pipeline, open to price, run, watch, stop, edit and delete. The open pipeline is in the URL (?lp=).",
175
+ "operations": [
176
+ "list_list_pipelines_enrichment_lists__list_id__pipelines_get"
177
+ ],
178
+ "tiers": [
179
+ "read"
180
+ ]
181
+ },
182
+ {
183
+ "name": "PipelineDetail",
184
+ "file": "components/pipeline-detail.tsx",
185
+ "purpose": "One list pipeline: price the run for this exact list (free estimate), run it behind a confirm showing that price, poll the run with per-step progress, stop it, turn it on or off, delete it, read its run history.",
186
+ "operations": [
187
+ "estimate_list_pipeline_enrichment_lists__list_id__pipelines__pipeline_id__estimate_post",
188
+ "run_list_pipeline_enrichment_lists__list_id__pipelines__pipeline_id__runs_post",
189
+ "get_pipeline_run_enrichment_lists_pipeline_runs__run_id__get",
190
+ "cancel_list_pipeline_run_enrichment_lists__list_id__pipelines__pipeline_id__cancel_post",
191
+ "list_list_pipeline_runs_enrichment_lists__list_id__pipelines__pipeline_id__runs_get",
192
+ "set_pipeline_enabled_enrichment_lists__list_id__pipelines__pipeline_id__enabled_post",
193
+ "delete_list_pipeline_enrichment_lists__list_id__pipelines__pipeline_id__delete",
194
+ "list_pipeline_step_options_enrichment_lists__list_id__pipeline_step_options_get"
195
+ ],
196
+ "tiers": [
197
+ "read",
198
+ "write",
199
+ "billable",
200
+ "destructive"
201
+ ]
202
+ },
203
+ {
204
+ "name": "PipelineEditor",
205
+ "file": "components/pipeline-editor.tsx",
206
+ "purpose": "Create or edit a list pipeline in a side sheet: pick steps from the configs the list can use, order them, turn steps off, fill-only-empty and skip-recent options. Saving never runs it.",
207
+ "operations": [
208
+ "list_pipeline_step_options_enrichment_lists__list_id__pipeline_step_options_get",
209
+ "create_list_pipeline_enrichment_lists__list_id__pipelines_post",
210
+ "update_list_pipeline_enrichment_lists__list_id__pipelines__pipeline_id__put"
211
+ ],
212
+ "tiers": [
213
+ "read",
214
+ "billable"
215
+ ]
216
+ },
217
+ {
218
+ "name": "PipelineTemplates",
219
+ "file": "components/pipeline-templates.tsx",
220
+ "purpose": "Pick a ready-made pipeline for the list; saved turned off. Adding one the list already has resets it (confirmed).",
221
+ "operations": [
222
+ "list_pipeline_templates_enrichment_lists_pipeline_templates_get",
223
+ "create_list_pipeline_from_template_enrichment_lists__list_id__pipelines_from_template_post"
121
224
  ],
122
225
  "tiers": [
123
226
  "read",
124
227
  "write"
125
228
  ]
229
+ },
230
+ {
231
+ "name": "AutoEnrichmentConfigs",
232
+ "file": "components/auto-enrichment-configs.tsx",
233
+ "purpose": "What a list enriches by itself as records are added: list, add, turn on or off, delete. Every change is confirmed and states that it spends credits with nobody confirming each record.",
234
+ "operations": [
235
+ "list_auto_enrichment_configs_enrichment_auto_enrichment_configs_get",
236
+ "get_auto_enrichment_config_enrichment_auto_enrichment_configs__config_id__get",
237
+ "create_auto_enrichment_config_enrichment_auto_enrichment_configs_post",
238
+ "update_auto_enrichment_config_enrichment_auto_enrichment_configs__config_id__patch",
239
+ "delete_auto_enrichment_config_enrichment_auto_enrichment_configs__config_id__delete",
240
+ "list_pipeline_step_options_enrichment_lists__list_id__pipeline_step_options_get"
241
+ ],
242
+ "tiers": [
243
+ "read",
244
+ "billable",
245
+ "destructive"
246
+ ]
247
+ },
248
+ {
249
+ "name": "AutoEnrichmentSettings",
250
+ "file": "components/auto-enrichment-settings.tsx",
251
+ "purpose": "Workspace-wide automatic enrichment for contacts and companies: on or off and the merge rule (keep edits, never overwrite, matched data wins). Per-field overrides are kept.",
252
+ "operations": [
253
+ "get_auto_enrichment_settings_enrichment_auto_enrichment_settings_get",
254
+ "update_auto_enrichment_settings_enrichment_auto_enrichment_settings__entity_type__put"
255
+ ],
256
+ "tiers": [
257
+ "read",
258
+ "billable"
259
+ ]
260
+ },
261
+ {
262
+ "name": "EnrichmentActivity",
263
+ "file": "components/enrichment-activity.tsx",
264
+ "purpose": "Free analytics for a chosen window: records enriched, success rate, results over time, daily activity and the fields filled.",
265
+ "operations": [
266
+ "get_enrichment_metrics_enrichment_analytics_metrics_get",
267
+ "get_enrichment_trends_enrichment_analytics_trends_get",
268
+ "get_enrichment_daily_activity_enrichment_analytics_daily_activity_get",
269
+ "get_enrichment_field_distribution_enrichment_analytics_field_distribution_get"
270
+ ],
271
+ "tiers": [
272
+ "read"
273
+ ]
126
274
  }
127
275
  ],
128
276
  "hooks": [
@@ -139,6 +287,10 @@
139
287
  {
140
288
  "file": "lib/enrichment-types.ts",
141
289
  "purpose": "Credit prices, field and job vocabularies, preflight/job/pipeline shapes, estimateCredits and isJobTerminal."
290
+ },
291
+ {
292
+ "file": "lib/pipeline-types.ts",
293
+ "purpose": "List pipeline, run, estimate, template, auto-enrichment and analytics shapes plus pure helpers (step builders, ordering, change detection, percent)."
142
294
  }
143
295
  ],
144
296
  "recipes": [
@@ -150,7 +302,7 @@
150
302
  {
151
303
  "file": "recipes/bulk-enrich-and-poll.ts",
152
304
  "title": "Enrich many contacts of a list and wait for the job",
153
- "when": "Filling work emails or phones for a list. Order: preflight (free: counts, missing provider keys and the credit quote) -> a human approves the quote -> start the job -> poll it (the API has no streams or webhook for completion) -> read provider errors if nothing was written. Contact ids must be on the list; ids not on it are skipped and not charged. Never enrich contacts you only have as masked search results: save them to a list first."
305
+ "when": "Filling work emails or phones for a list. Order: preflight (free: counts, missing provider keys and the credit quote) -> a human approves the quote -> create or reuse the field's pipeline and run it -> poll it (the API has no streams or webhook for completion) -> read provider errors if nothing was written. Contact ids must be on the list; ids not on it are skipped and not charged. Never enrich contacts you only have as masked search results: save them to a list first."
154
306
  },
155
307
  {
156
308
  "file": "recipes/waterfall-pipeline.ts",
@@ -180,7 +332,7 @@
180
332
  {
181
333
  "id": "credits",
182
334
  "where": "api",
183
- "description": "The workspace has credits for graph8-funded providers. The API has no balance read, so the UI shows estimates only; a run without enough credits fails with 402.",
335
+ "description": "The workspace has credits for graph8-funded providers. There is no standalone balance read; a pipeline's price estimate returns available_credits beside the quote, and a run without enough credits fails with 402.",
184
336
  "verify": "A one-contact enrichment succeeds."
185
337
  }
186
338
  ],
@@ -201,7 +353,7 @@
201
353
  "defaults": [
202
354
  {
203
355
  "decision": "Providers a bulk run tries",
204
- "default": "prospeo then dropcontact (the API's own default), filtered to those in the provider catalog; editable in the panel",
356
+ "default": "The API's own per field (work email: prospeo then dropcontact; phones: leadmagic, prospeo, apollo), kept to providers in the catalog that the field supports; editable in the panel. A list that already has a pipeline for the field runs with that pipeline's providers",
205
357
  "askHuman": false
206
358
  },
207
359
  {
@@ -0,0 +1,134 @@
1
+ "use client";
2
+
3
+ /**
4
+ * AutoEnrichmentConfigs: the enrichments a list runs by itself. Each one enriches every record that is ADDED to the
5
+ * list from then on, with a provider waterfall or an AI group, and charges for it with nobody confirming each record.
6
+ *
7
+ * SDK operations, in order:
8
+ * 1. listAutoEnrichmentConfigs GET /enrichment/auto-enrichment/configs?audience_id (read, free) -> { configs[], total }
9
+ * 2. listPipelineStepOptions GET /enrichment/lists/{list_id}/pipeline-step-options (read, free) names the column each config uses
10
+ * (and is exactly the set the API accepts for a new config: active, and global or available on this list)
11
+ * 3. getAutoEnrichmentConfig GET /enrichment/auto-enrichment/configs/{config_id} (read, free) loaded before Turn off or Delete is offered
12
+ * 4. createAutoEnrichmentConfig POST /enrichment/auto-enrichment/configs { audience_id, enrichment_type, column_id, trigger_on_insert }
13
+ * (billable, ConfirmSpendDialog)
14
+ * 5. updateAutoEnrichmentConfig PATCH /enrichment/auto-enrichment/configs/{config_id} { trigger_on_insert } (billable tier, ConfirmSpendDialog)
15
+ * 6. deleteAutoEnrichmentConfig DELETE /enrichment/auto-enrichment/configs/{config_id} (destructive, ConfirmSpendDialog)
16
+ *
17
+ * What the confirm says is what the backend does: the trigger is an INSERT trigger. Records already on the list are
18
+ * not enriched when a config is created, and edits to a record do not re-run it. No per-record price is published for
19
+ * this call, so the confirm states that instead of showing a number.
20
+ */
21
+
22
+ import { useState } from "react";
23
+ import { Button, Label } from "@graph8/sdk/ui";
24
+ import { ApiError } from "@/g8/components/api-error";
25
+ import { ConfirmSpendDialog } from "@/g8/components/confirm-spend-dialog";
26
+ import { useConfirmAction } from "@/g8/components/confirmed-action";
27
+ import { EmptyState } from "@/g8/components/empty-state";
28
+ import { SectionCard } from "@/g8/components/screen/section-card";
29
+ import { StatusPill } from "@/g8/components/screen/status-pill";
30
+ import { useG8Mutation } from "@/g8/hooks/use-g8-mutation";
31
+ import { useG8Query } from "@/g8/hooks/use-g8-query";
32
+ import { g8Delete, g8Get, g8Patch, g8Post } from "@/g8/lib/g8-client";
33
+ import { itemsOf } from "../lib/pipeline-types";
34
+ import type { AutoConfig, StepOption } from "../lib/pipeline-types";
35
+
36
+ export interface AutoEnrichmentConfigsProps {
37
+ listId: number;
38
+ className?: string;
39
+ }
40
+
41
+ const day = (iso?: string | null) => (iso ? new Date(iso).toLocaleDateString(undefined, { dateStyle: "medium" }) : "");
42
+ const ONGOING = "From now on, every record added to this list is enriched automatically and charged, with nobody confirming each one. Records already on the list are not touched, and editing a record does not run it again. The API publishes no per-record price for this, so no total is shown: check the provider costs on the Providers tab.";
43
+
44
+ function ConfigRow({ config, label, onChanged }: { config: AutoConfig; label: string; onChanged: () => void }) {
45
+ const [open, setOpen] = useState(false);
46
+ const { ask, dialog, failure } = useConfirmAction();
47
+ const detail = useG8Query(async (signal) => (await g8Get<AutoConfig>(`/enrichment/auto-enrichment/configs/${config.id}`, undefined, { signal })).data, [config.id], { enabled: open });
48
+ const fresh = detail.data;
49
+ const toggle = (next: boolean) => ask({
50
+ tier: "billable",
51
+ title: `${next ? "Turn on" : "Turn off"} automatic enrichment with ${label}`,
52
+ confirmLabel: next ? "Turn on" : "Turn off",
53
+ description: next ? ONGOING : "New records added to this list will no longer be enriched with this. Records already enriched keep their values.",
54
+ run: () => g8Patch(`/enrichment/auto-enrichment/configs/${config.id}`, { trigger_on_insert: next }),
55
+ onDone: () => { void detail.refetch(); onChanged(); },
56
+ });
57
+ const remove = () => ask({
58
+ tier: "destructive",
59
+ title: `Delete automatic enrichment with ${label}`,
60
+ description: "New records will no longer be enriched with this. Values already written stay on the records.",
61
+ affected: 1,
62
+ tolerateStatus: [404],
63
+ run: () => g8Delete(`/enrichment/auto-enrichment/configs/${config.id}`),
64
+ onDone: onChanged,
65
+ });
66
+ return (
67
+ <li className="flex flex-col gap-2 px-4 py-3" data-testid="auto-config">
68
+ <div className="flex items-center justify-between gap-3">
69
+ <button type="button" className="min-w-0 text-left" aria-expanded={open} onClick={() => setOpen(!open)}>
70
+ <span className="block truncate text-sm font-medium">{label}</span>
71
+ <span className="block text-xs text-muted-foreground">{config.enrichment_type === "ai" ? "AI group" : "Provider waterfall"}</span>
72
+ </button>
73
+ <StatusPill tone={config.trigger_on_insert ? "positive" : "neutral"} dot>{config.trigger_on_insert ? "Enriching new records" : "Off"}</StatusPill>
74
+ </div>
75
+ {open ? (
76
+ <div className="flex flex-col gap-2 rounded-md border p-3">
77
+ {detail.error ? <ApiError error={detail.error} title="Could not load this setting" onRetry={() => void detail.refetch()} /> : null}
78
+ {detail.loading && !fresh ? <p className="text-sm text-muted-foreground">Loading...</p> : null}
79
+ {fresh ? <p className="text-xs text-muted-foreground">Added {day(fresh.created_at) || "on an unknown date"}. Applies to records added to the list; it does not re-run on edits.</p> : null}
80
+ <div className="flex gap-2">
81
+ <Button size="sm" variant="outline" disabled={!fresh} onClick={() => fresh && toggle(!fresh.trigger_on_insert)}>{fresh?.trigger_on_insert === false ? "Turn on" : "Turn off"}</Button>
82
+ <Button size="sm" variant="ghost" disabled={!fresh} onClick={remove}>Delete</Button>
83
+ </div>
84
+ {failure ? <ApiError error={failure} title="That did not go through" /> : null}
85
+ </div>
86
+ ) : null}
87
+ <ConfirmSpendDialog {...dialog} />
88
+ </li>
89
+ );
90
+ }
91
+
92
+ export function AutoEnrichmentConfigs({ listId, className }: AutoEnrichmentConfigsProps) {
93
+ const [pick, setPick] = useState("");
94
+ const [confirming, setConfirming] = useState(false);
95
+ const configs = useG8Query(async (signal) => itemsOf<AutoConfig>((await g8Get("/enrichment/auto-enrichment/configs", { audience_id: listId }, { signal })).data, "configs"), [listId]);
96
+ const options = useG8Query(async (signal) => itemsOf<StepOption>((await g8Get(`/enrichment/lists/${listId}/pipeline-step-options`, undefined, { signal })).data), [listId], { key: ["enrichment", "step-options", listId], staleTime: 30_000 });
97
+ const rows = configs.data ?? [];
98
+ const menu = options.data ?? [];
99
+ const labelOf = (c: AutoConfig) => menu.find((o) => o.config_ref === c.column_id && o.type === c.enrichment_type)?.name ?? "A column that is no longer available";
100
+ const free = menu.filter((o) => !rows.some((c) => c.column_id === o.config_ref && c.enrichment_type === o.type));
101
+ const chosen = free.find((o) => `${o.type}:${o.config_ref}` === pick);
102
+ const create = useG8Mutation(
103
+ async () => (await g8Post<AutoConfig>("/enrichment/auto-enrichment/configs", { audience_id: listId, enrichment_type: chosen?.type, column_id: chosen?.config_ref, trigger_on_insert: true })).data,
104
+ { onSuccess: () => { setConfirming(false); setPick(""); void configs.refetch(); }, onError: () => setConfirming(false) },
105
+ );
106
+
107
+ return (
108
+ <div className={`flex flex-col gap-4 ${className ?? ""}`}>
109
+ <SectionCard title="Automatic enrichment for this list" description="Enrich every new record as it arrives. This spends credits without asking each time." flush>
110
+ {configs.error ? <div className="p-3"><ApiError error={configs.error} title="Could not load automatic enrichment" onRetry={() => void configs.refetch()} /></div> : null}
111
+ {!configs.error && configs.loading && !configs.data ? <p className="p-4 text-sm text-muted-foreground">Loading...</p> : null}
112
+ {!configs.error && configs.data && rows.length === 0 ? <EmptyState title="Nothing runs automatically" description="Pick a column below and new records on this list will be enriched as they are added." /> : null}
113
+ <ul className="divide-y">{(configs.error ? [] : rows).map((c) => <ConfigRow key={c.id} config={c} label={labelOf(c)} onChanged={() => void configs.refetch()} />)}</ul>
114
+ </SectionCard>
115
+
116
+ <SectionCard title="Add automatic enrichment" description="Choose what to run on each new record.">
117
+ <div className="flex flex-col gap-3">
118
+ {options.error ? <ApiError error={options.error} title="Could not load the columns you can use" onRetry={() => void options.refetch()} /> : null}
119
+ <div className="flex flex-col gap-1">
120
+ <Label htmlFor="ae-pick">Run on every new record</Label>
121
+ <select id="ae-pick" className="h-9 rounded-md border bg-background px-2 text-sm" value={pick} disabled={options.loading} onChange={(e) => setPick(e.target.value)}>
122
+ <option value="">{options.loading ? "Loading..." : free.length ? "Choose a column" : "Nothing left to add"}</option>
123
+ {free.map((o) => <option key={`${o.type}:${o.config_ref}`} value={`${o.type}:${o.config_ref}`}>{o.name}</option>)}
124
+ </select>
125
+ </div>
126
+ {create.error ? <ApiError error={create.error} title="Could not turn it on" /> : null}
127
+ <div><Button disabled={!chosen} onClick={() => setConfirming(true)}>Turn on for new records</Button></div>
128
+ </div>
129
+ </SectionCard>
130
+ <ConfirmSpendDialog open={confirming} tier="billable" title={`Enrich new records automatically with ${chosen?.name ?? "this column"}`} description={ONGOING}
131
+ confirmLabel="Turn on" confirming={create.loading} onConfirm={() => void create.mutate(undefined)} onCancel={() => setConfirming(false)} />
132
+ </div>
133
+ );
134
+ }
@@ -0,0 +1,82 @@
1
+ "use client";
2
+
3
+ /**
4
+ * AutoEnrichmentSettings: the workspace-wide switch and merge rule for automatic enrichment, one card for contacts and
5
+ * one for companies. The rule decides who wins when enriched data disagrees with what is on a record.
6
+ *
7
+ * SDK operations, in order:
8
+ * 1. getAutoEnrichmentSettings GET /enrichment/auto-enrichment/settings (read, free) -> { contact, company } each
9
+ * { enabled, default_rule: sticky | user_wins | mashup_wins, per_field_overrides }
10
+ * 2. updateAutoEnrichmentSettings PUT /enrichment/auto-enrichment/settings/{entity_type} (billable, ConfirmSpendDialog)
11
+ * sends enabled + default_rule + the per-field overrides it loaded, so saving one never wipes the others. The API
12
+ * defaults `enabled` to true, so it is always sent explicitly.
13
+ *
14
+ * Save is disabled until the settings have loaded and while nothing changed. The confirm states the real effect (what
15
+ * the rule does, from the merge handler) and that graph8 grades turning this on as a billable change; the API publishes
16
+ * no price for it, so none is shown. Needs the settings permission: a 403 is shown as such, not as an empty card.
17
+ */
18
+
19
+ import { useState } from "react";
20
+ import { Button } from "@graph8/sdk/ui";
21
+ import { ApiError } from "@/g8/components/api-error";
22
+ import { ConfirmSpendDialog } from "@/g8/components/confirm-spend-dialog";
23
+ import { SectionCard } from "@/g8/components/screen/section-card";
24
+ import { StatusPill } from "@/g8/components/screen/status-pill";
25
+ import { useG8Mutation } from "@/g8/hooks/use-g8-mutation";
26
+ import { useBrand } from "@/g8/hooks/use-brand";
27
+ import { useG8Query } from "@/g8/hooks/use-g8-query";
28
+ import { g8Get, g8Put } from "@/g8/lib/g8-client";
29
+ import { plural } from "@/g8/lib/plural";
30
+ import { MERGE_RULES, MERGE_RULE_COPY } from "../lib/pipeline-types";
31
+ import type { AutoSettings, MergeRule } from "../lib/pipeline-types";
32
+
33
+ const KINDS = [{ id: "contact", label: "Contacts" }, { id: "company", label: "Companies" }] as const;
34
+
35
+ function KindCard({ settings, label, onSaved }: { settings: AutoSettings; label: string; onSaved: () => void }) {
36
+ const brand = useBrand();
37
+ const [enabled, setEnabled] = useState(settings.enabled);
38
+ const [rule, setRule] = useState<MergeRule>(settings.default_rule);
39
+ const [confirming, setConfirming] = useState(false);
40
+ const overrides = Object.keys(settings.per_field_overrides ?? {}).length;
41
+ const save = useG8Mutation(
42
+ () => g8Put(`/enrichment/auto-enrichment/settings/${settings.entity_type}`, { enabled, default_rule: rule, per_field_overrides: settings.per_field_overrides ?? {} }),
43
+ { onSuccess: () => { setConfirming(false); onSaved(); }, onError: () => setConfirming(false) },
44
+ );
45
+ const changed = enabled !== settings.enabled || rule !== settings.default_rule;
46
+ return (
47
+ <SectionCard title={label} actions={<StatusPill tone={settings.enabled ? "positive" : "neutral"} dot>{settings.enabled ? "On" : "Off"}</StatusPill>}>
48
+ <div className="flex flex-col gap-3">
49
+ <label className="flex items-center gap-2 text-sm"><input type="checkbox" checked={enabled} onChange={(e) => setEnabled(e.target.checked)} /> Enrich {label.toLowerCase()} automatically</label>
50
+ <fieldset className="flex flex-col gap-2" aria-label={`${label} merge rule`}>
51
+ <legend className="text-sm font-medium">When enriched data differs from the record</legend>
52
+ {MERGE_RULES.map((r) => (
53
+ <label key={r} className="flex items-start gap-2 text-sm">
54
+ <input type="radio" name={`rule-${settings.entity_type}`} className="mt-1" checked={rule === r} onChange={() => setRule(r)} />
55
+ <span><span className="font-medium">{MERGE_RULE_COPY[r].label}</span><span className="block text-xs text-muted-foreground">{MERGE_RULE_COPY[r].help}</span></span>
56
+ </label>
57
+ ))}
58
+ </fieldset>
59
+ {overrides ? <p className="text-xs text-muted-foreground">{plural(overrides, "field")} follow their own rule. Saving keeps them as they are.</p> : null}
60
+ {save.error ? <ApiError error={save.error} title={`Could not save ${label.toLowerCase()} settings`} /> : null}
61
+ <div><Button disabled={!changed} onClick={() => setConfirming(true)}>Save {label.toLowerCase()} settings</Button></div>
62
+ </div>
63
+ <ConfirmSpendDialog open={confirming} tier="billable" title={`Save ${label.toLowerCase()} settings`}
64
+ description={`${enabled ? `Automatic enrichment of ${label.toLowerCase()} will be ON` : `Automatic enrichment of ${label.toLowerCase()} will be OFF`}, with the rule "${MERGE_RULE_COPY[rule].label}": ${MERGE_RULE_COPY[rule].help} ${brand.linkLabel} treats turning this on as a billable change and publishes no price for it, so no total is shown.`}
65
+ confirmLabel="Save" confirming={save.loading} onConfirm={() => void save.mutate(undefined)} onCancel={() => setConfirming(false)} />
66
+ </SectionCard>
67
+ );
68
+ }
69
+
70
+ export function AutoEnrichmentSettings({ className }: { className?: string }) {
71
+ const q = useG8Query(async (signal) => (await g8Get<Partial<Record<"contact" | "company", AutoSettings>>>("/enrichment/auto-enrichment/settings", undefined, { signal })).data, []);
72
+ if (q.error) return <ApiError error={q.error} title="Could not load the workspace settings" onRetry={() => void q.refetch()} />;
73
+ if (!q.data) return <p className="text-sm text-muted-foreground">Loading settings...</p>;
74
+ return (
75
+ <div className={`grid gap-4 lg:grid-cols-2 ${className ?? ""}`}>
76
+ {KINDS.map((k) => {
77
+ const s = q.data?.[k.id];
78
+ return s ? <KindCard key={`${k.id}-${s.enabled}-${s.default_rule}`} settings={{ ...s, entity_type: k.id }} label={k.label} onSaved={() => void q.refetch()} /> : null;
79
+ })}
80
+ </div>
81
+ );
82
+ }