@graph8/sdk 0.370.0 → 0.373.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 (466) hide show
  1. package/README.md +19 -0
  2. package/blocks/_foundation/README.md +14 -0
  3. package/blocks/_foundation/block.json +44 -0
  4. package/blocks/_foundation/components/confirm-spend-dialog.tsx +15 -8
  5. package/blocks/_foundation/components/empty-state.tsx +5 -2
  6. package/blocks/_foundation/components/list-select.tsx +112 -0
  7. package/blocks/_foundation/components/paging-notices.tsx +55 -0
  8. package/blocks/_foundation/components/screen/detail-panel.tsx +2 -1
  9. package/blocks/_foundation/components/screen/filter-controls.tsx +92 -0
  10. package/blocks/_foundation/components/screen/index.ts +1 -0
  11. package/blocks/_foundation/components/screen/split-view.tsx +1 -1
  12. package/blocks/_foundation/hooks/use-all-pages.ts +54 -0
  13. package/blocks/_foundation/hooks/use-load-more-list.ts +61 -0
  14. package/blocks/_foundation/hooks/use-url-filters.ts +93 -0
  15. package/blocks/_foundation/lib/paging.ts +57 -0
  16. package/blocks/_foundation/lib/use-debounced-value.ts +13 -0
  17. package/blocks/agents/README.md +81 -4
  18. package/blocks/agents/block.json +311 -2
  19. package/blocks/agents/components/agent-activity.tsx +112 -0
  20. package/blocks/agents/components/agent-approvals.tsx +135 -0
  21. package/blocks/agents/components/agent-builder.tsx +17 -3
  22. package/blocks/agents/components/agent-conversations.tsx +143 -0
  23. package/blocks/agents/components/agent-knowledge-panel.tsx +2 -2
  24. package/blocks/agents/components/agent-operators.tsx +164 -0
  25. package/blocks/agents/components/agent-run-detail.tsx +20 -3
  26. package/blocks/agents/components/agent-runs.tsx +3 -3
  27. package/blocks/agents/components/agent-skills-panel.tsx +7 -7
  28. package/blocks/agents/components/agent-test-history.tsx +121 -0
  29. package/blocks/agents/components/agents-screen.tsx +53 -11
  30. package/blocks/agents/components/assistant-sessions.tsx +150 -0
  31. package/blocks/agents/components/duplicate-agent-button.tsx +42 -0
  32. package/blocks/agents/components/from-template-button.tsx +65 -0
  33. package/blocks/agents/components/knowledge-browser.tsx +107 -0
  34. package/blocks/agents/components/knowledge-detail.tsx +156 -0
  35. package/blocks/agents/components/knowledge-form.tsx +69 -0
  36. package/blocks/agents/components/name-dialog.tsx +32 -0
  37. package/blocks/agents/components/receptionist-button.tsx +46 -0
  38. package/blocks/agents/components/save-as-template-button.tsx +32 -0
  39. package/blocks/agents/components/skill-editor.tsx +147 -0
  40. package/blocks/agents/components/skill-library.tsx +111 -0
  41. package/blocks/agents/lib/agent-types.ts +7 -1
  42. package/blocks/agents/lib/facts.tsx +13 -0
  43. package/blocks/agents/lib/knowledge-utils.ts +49 -0
  44. package/blocks/agents/lib/load-more.tsx +141 -0
  45. package/blocks/agents/lib/skill-utils.ts +91 -0
  46. package/blocks/agents/recipes/create-agent-and-attach-skill.ts +1 -1
  47. package/blocks/analytics/components/analytics-screen.tsx +16 -3
  48. package/blocks/analytics/components/kpi-tiles.tsx +1 -1
  49. package/blocks/analytics/components/report-builder.tsx +15 -2
  50. package/blocks/appointments/README.md +6 -0
  51. package/blocks/appointments/block.json +27 -0
  52. package/blocks/appointments/components/booking-page.tsx +2 -2
  53. package/blocks/appointments/components/meeting-contact-links.tsx +49 -0
  54. package/blocks/appointments/components/meeting-detail.tsx +2 -2
  55. package/blocks/appointments/components/meeting-list.tsx +29 -13
  56. package/blocks/appointments/components/record-meetings-tab.tsx +92 -0
  57. package/blocks/campaigns/components/campaign-assets.tsx +1 -1
  58. package/blocks/campaigns/components/campaign-launch-step.tsx +16 -11
  59. package/blocks/campaigns/components/campaign-metrics.tsx +1 -1
  60. package/blocks/campaigns/components/campaign-wizard.tsx +10 -5
  61. package/blocks/campaigns/components/icp-detail.tsx +11 -2
  62. package/blocks/campaigns/components/icp-editor.tsx +8 -3
  63. package/blocks/campaigns/components/persona-detail.tsx +11 -2
  64. package/blocks/campaigns/components/persona-editor.tsx +6 -1
  65. package/blocks/campaigns/lib/campaigns-utils.ts +4 -4
  66. package/blocks/coach/components/call-scorecard.tsx +7 -7
  67. package/blocks/company-intelligence/README.md +132 -0
  68. package/blocks/company-intelligence/block.json +318 -0
  69. package/blocks/company-intelligence/components/company-intelligence-screen.tsx +114 -0
  70. package/blocks/company-intelligence/components/company-intelligence-tab.tsx +88 -0
  71. package/blocks/company-intelligence/components/company-profile.tsx +68 -0
  72. package/blocks/company-intelligence/components/intelligence-sources.tsx +63 -0
  73. package/blocks/company-intelligence/components/report-detail.tsx +189 -0
  74. package/blocks/company-intelligence/components/research-reports.tsx +136 -0
  75. package/blocks/company-intelligence/components/research-run.tsx +161 -0
  76. package/blocks/company-intelligence/components/source-detail.tsx +117 -0
  77. package/blocks/company-intelligence/components/source-view.tsx +274 -0
  78. package/blocks/company-intelligence/components/wiki-document-detail.tsx +116 -0
  79. package/blocks/company-intelligence/components/wiki-documents.tsx +66 -0
  80. package/blocks/company-intelligence/hooks/use-intelligence.ts +173 -0
  81. package/blocks/company-intelligence/lib/intelligence-types.ts +230 -0
  82. package/blocks/company-intelligence/lib/safe-markdown.tsx +150 -0
  83. package/blocks/company-intelligence/recipes/read-competitors-and-news.ts +33 -0
  84. package/blocks/company-intelligence/recipes/research-your-website.ts +43 -0
  85. package/blocks/company-intelligence/recipes/write-the-research-reports.ts +54 -0
  86. package/blocks/copilot/components/copilot-memory.tsx +6 -2
  87. package/blocks/copilot/components/copilot-panel.tsx +1 -1
  88. package/blocks/copilot/components/copilot-team-chat.tsx +6 -1
  89. package/blocks/crm/README.md +6 -0
  90. package/blocks/crm/block.json +53 -4
  91. package/blocks/crm/components/companies-screen.tsx +23 -9
  92. package/blocks/crm/components/company-detail.tsx +2 -2
  93. package/blocks/crm/components/contact-detail.tsx +4 -4
  94. package/blocks/crm/components/contact-lookup-link.tsx +44 -0
  95. package/blocks/crm/components/contacts-screen.tsx +31 -13
  96. package/blocks/crm/components/dedupe-review.tsx +6 -1
  97. package/blocks/crm/components/import-wizard.tsx +3 -7
  98. package/blocks/crm/components/list-select.tsx +20 -0
  99. package/blocks/crm/components/record-engagement-tab.tsx +103 -0
  100. package/blocks/crm/components/record-form.tsx +1 -1
  101. package/blocks/crm/components/tasks-screen.tsx +35 -15
  102. package/blocks/crm/hooks/use-all-lists.ts +18 -0
  103. package/blocks/crm/hooks/use-page-query.ts +3 -1
  104. package/blocks/crm/lib/crm-types.ts +14 -0
  105. package/blocks/crm/lib/read-lists.ts +16 -0
  106. package/blocks/deals/README.md +24 -6
  107. package/blocks/deals/block.json +151 -2
  108. package/blocks/deals/components/close-deal-dialog.tsx +169 -0
  109. package/blocks/deals/components/deal-contacts-editor.tsx +134 -0
  110. package/blocks/deals/components/deal-detail.tsx +2 -2
  111. package/blocks/deals/components/deal-filters.tsx +65 -0
  112. package/blocks/deals/components/deal-line-items.tsx +120 -0
  113. package/blocks/deals/components/deal-notes-tab.tsx +97 -0
  114. package/blocks/deals/components/deal-related.tsx +30 -9
  115. package/blocks/deals/components/deal-tasks-tab.tsx +88 -0
  116. package/blocks/deals/components/deals-screen.tsx +57 -22
  117. package/blocks/deals/components/forecast-view.tsx +4 -4
  118. package/blocks/deals/components/pipeline-board.tsx +8 -6
  119. package/blocks/deals/components/pipeline-editor.tsx +132 -0
  120. package/blocks/deals/components/record-deals-tab.tsx +62 -0
  121. package/blocks/deals/components/stage-editor.tsx +1 -1
  122. package/blocks/deals/hooks/use-pipeline-deals.ts +17 -4
  123. package/blocks/deals/lib/deal-extras.ts +156 -0
  124. package/blocks/dialer/README.md +14 -5
  125. package/blocks/dialer/block.json +17 -2
  126. package/blocks/dialer/components/call-contact-button.tsx +26 -9
  127. package/blocks/dialer/components/call-log-screen.tsx +4 -1
  128. package/blocks/dialer/components/call-log.tsx +16 -4
  129. package/blocks/dialer/components/call-queue.tsx +3 -3
  130. package/blocks/dialer/components/dialer-screen.tsx +69 -27
  131. package/blocks/dialer/components/disposition-panel.tsx +1 -1
  132. package/blocks/dialer/components/record-calls-tab.tsx +101 -0
  133. package/blocks/dialer/components/session-start-form.tsx +58 -11
  134. package/blocks/dialer/components/softphone.tsx +1 -1
  135. package/blocks/enrichment/README.md +16 -6
  136. package/blocks/enrichment/block.json +19 -7
  137. package/blocks/enrichment/components/bulk-enrich-panel.tsx +76 -27
  138. package/blocks/enrichment/components/email-verify-badge.tsx +3 -3
  139. package/blocks/enrichment/components/enrich-button.tsx +1 -1
  140. package/blocks/enrichment/components/enrichment-screen.tsx +70 -17
  141. package/blocks/enrichment/components/waterfall-config.tsx +27 -7
  142. package/blocks/enrichment/lib/enrichment-types.ts +39 -0
  143. package/blocks/enrichment/recipes/bulk-enrich-and-poll.ts +15 -4
  144. package/blocks/forms/README.md +8 -0
  145. package/blocks/forms/block.json +107 -0
  146. package/blocks/forms/components/form-activity.tsx +71 -0
  147. package/blocks/forms/components/form-backfill.tsx +108 -0
  148. package/blocks/forms/components/form-builder.tsx +1 -1
  149. package/blocks/forms/components/form-embed.tsx +1 -1
  150. package/blocks/forms/components/form-groups.tsx +151 -0
  151. package/blocks/forms/components/form-mapping-editor.tsx +6 -9
  152. package/blocks/forms/components/form-route-history.tsx +72 -0
  153. package/blocks/forms/components/form-saved-views.tsx +81 -0
  154. package/blocks/forms/components/forms-screen.tsx +51 -17
  155. package/blocks/forms/components/more-rows.tsx +30 -0
  156. package/blocks/forms/components/submissions-export.tsx +67 -0
  157. package/blocks/forms/components/submissions-table.tsx +15 -6
  158. package/blocks/forms/lib/forms-extra.ts +67 -0
  159. package/blocks/inbox/README.md +5 -0
  160. package/blocks/inbox/block.json +15 -0
  161. package/blocks/inbox/components/record-conversations-tab.tsx +154 -0
  162. package/blocks/inbox/components/thread-badge.tsx +2 -2
  163. package/blocks/inbox/components/thread-view.tsx +1 -1
  164. package/blocks/integrations/README.md +54 -1
  165. package/blocks/integrations/block.json +189 -15
  166. package/blocks/integrations/components/ad-accounts.tsx +82 -0
  167. package/blocks/integrations/components/connection-health.tsx +59 -0
  168. package/blocks/integrations/components/crm-detail.tsx +20 -1
  169. package/blocks/integrations/components/crm-records.tsx +103 -0
  170. package/blocks/integrations/components/field-mappings.tsx +61 -0
  171. package/blocks/integrations/components/integration-list.tsx +4 -4
  172. package/blocks/integrations/components/integrations-screen.tsx +20 -3
  173. package/blocks/integrations/components/migration-panel.tsx +133 -0
  174. package/blocks/integrations/components/sugarcrm-connect.tsx +95 -0
  175. package/blocks/integrations/components/sync-status.tsx +6 -6
  176. package/blocks/integrations/components/sync-triggers.tsx +134 -0
  177. package/blocks/integrations/components/webhook-detail.tsx +26 -7
  178. package/blocks/integrations/components/webhook-manager.tsx +30 -17
  179. package/blocks/integrations/components/workspace-tools.tsx +127 -0
  180. package/blocks/integrations/lib/crm-utils.ts +39 -0
  181. package/blocks/integrations/lib/facts.tsx +13 -0
  182. package/blocks/integrations/lib/integrations-utils.ts +5 -0
  183. package/blocks/integrations/lib/load-more.tsx +141 -0
  184. package/blocks/intent/components/account-intent-score.tsx +5 -5
  185. package/blocks/intent/components/intent-feed.tsx +8 -8
  186. package/blocks/intent/components/intent-keyword-manager.tsx +8 -8
  187. package/blocks/intent/lib/intent-utils.ts +4 -4
  188. package/blocks/lifecycle/components/account-related.tsx +8 -1
  189. package/blocks/lifecycle/components/churn-list.tsx +5 -2
  190. package/blocks/lifecycle/components/customer-table.tsx +1 -1
  191. package/blocks/lists/README.md +7 -1
  192. package/blocks/lists/block.json +31 -3
  193. package/blocks/lists/components/add-company-people-to-list-button.tsx +73 -0
  194. package/blocks/lists/components/add-to-list-button.tsx +17 -7
  195. package/blocks/lists/components/list-picker.tsx +13 -3
  196. package/blocks/lists/components/list-table.tsx +1 -1
  197. package/blocks/lists/components/lists-screen.tsx +4 -2
  198. package/blocks/lists/components/record-lists-tab.tsx +99 -0
  199. package/blocks/lists/components/suppression-manager.tsx +27 -6
  200. package/blocks/lists/components/suppressions-screen.tsx +21 -12
  201. package/blocks/mailboxes/block.json +4 -0
  202. package/blocks/mailboxes/components/connect-mailbox.tsx +9 -8
  203. package/blocks/mailboxes/components/domain-detail.tsx +10 -4
  204. package/blocks/mailboxes/components/domain-purchase.tsx +14 -11
  205. package/blocks/mailboxes/components/mailbox-detail.tsx +3 -2
  206. package/blocks/mailboxes/components/mailbox-list.tsx +8 -3
  207. package/blocks/mailboxes/components/mailboxes-screen.tsx +8 -3
  208. package/blocks/mailboxes/components/warmup-health.tsx +20 -20
  209. package/blocks/mailboxes/lib/mailboxes-utils.ts +4 -4
  210. package/blocks/mailboxes/lib/use-provider-domains.ts +23 -0
  211. package/blocks/newsletter/README.md +12 -0
  212. package/blocks/newsletter/block.json +117 -0
  213. package/blocks/newsletter/components/issue-scheduler.tsx +2 -2
  214. package/blocks/newsletter/components/issue-versions.tsx +93 -0
  215. package/blocks/newsletter/components/more-rows.tsx +30 -0
  216. package/blocks/newsletter/components/newsletter-editor.tsx +1 -1
  217. package/blocks/newsletter/components/newsletter-list-syncs.tsx +121 -0
  218. package/blocks/newsletter/components/newsletter-screen.tsx +36 -13
  219. package/blocks/newsletter/components/newsletter-settings.tsx +211 -0
  220. package/blocks/newsletter/components/newsletter-stats.tsx +2 -2
  221. package/blocks/newsletter/components/newsletter-templates.tsx +133 -0
  222. package/blocks/newsletter/components/subscriber-table.tsx +5 -7
  223. package/blocks/newsletter/components/subscriber-timeline.tsx +65 -0
  224. package/blocks/newsletter/lib/newsletter-extra.ts +60 -0
  225. package/blocks/nurture/components/nurture-builder.tsx +10 -2
  226. package/blocks/nurture/components/nurture-enroll.tsx +6 -7
  227. package/blocks/nurture/components/nurture-form.tsx +5 -8
  228. package/blocks/nurture/components/nurture-screen.tsx +16 -5
  229. package/blocks/nurture/components/nurture-stats.tsx +5 -4
  230. package/blocks/objects/README.md +1 -1
  231. package/blocks/objects/block.json +13 -5
  232. package/blocks/objects/components/attribute-field-input.tsx +14 -1
  233. package/blocks/objects/components/object-record-detail.tsx +8 -1
  234. package/blocks/objects/components/object-schema-editor.tsx +1 -1
  235. package/blocks/objects/components/record-roles-panel.tsx +15 -5
  236. package/blocks/pages/README.md +14 -0
  237. package/blocks/pages/block.json +113 -1
  238. package/blocks/pages/components/more-rows.tsx +30 -0
  239. package/blocks/pages/components/page-ai-tools.tsx +196 -0
  240. package/blocks/pages/components/page-analytics.tsx +176 -0
  241. package/blocks/pages/components/page-clone.tsx +99 -0
  242. package/blocks/pages/components/page-domains.tsx +167 -0
  243. package/blocks/pages/components/page-editor.tsx +1 -1
  244. package/blocks/pages/components/page-generation-status.tsx +48 -0
  245. package/blocks/pages/components/page-tracking.tsx +137 -0
  246. package/blocks/pages/components/pages-screen.tsx +57 -16
  247. package/blocks/pages/components/seo-report.tsx +6 -1
  248. package/blocks/pages/lib/studio.ts +7 -0
  249. package/blocks/phone-numbers/README.md +74 -0
  250. package/blocks/phone-numbers/block.json +262 -0
  251. package/blocks/phone-numbers/components/a2p-registration.tsx +230 -0
  252. package/blocks/phone-numbers/components/assign-number.tsx +104 -0
  253. package/blocks/phone-numbers/components/number-search.tsx +239 -0
  254. package/blocks/phone-numbers/components/number-settings.tsx +134 -0
  255. package/blocks/phone-numbers/components/number-usage.tsx +97 -0
  256. package/blocks/phone-numbers/components/phone-number-detail.tsx +84 -0
  257. package/blocks/phone-numbers/components/phone-number-list.tsx +110 -0
  258. package/blocks/phone-numbers/components/phone-numbers-screen.tsx +201 -0
  259. package/blocks/phone-numbers/components/register-owned-number.tsx +98 -0
  260. package/blocks/phone-numbers/components/release-number.tsx +126 -0
  261. package/blocks/phone-numbers/hooks/use-phone-numbers.ts +58 -0
  262. package/blocks/phone-numbers/lib/phone-numbers-utils.ts +202 -0
  263. package/blocks/phone-numbers/recipes/01-search-and-buy-number.ts +49 -0
  264. package/blocks/phone-numbers/recipes/02-assign-number-to-rep.ts +25 -0
  265. package/blocks/phone-numbers/recipes/03-audit-numbers.ts +36 -0
  266. package/blocks/phone-numbers/recipes/04-register-text-messaging.ts +39 -0
  267. package/blocks/pickers/README.md +23 -0
  268. package/blocks/pickers/block.json +103 -0
  269. package/blocks/pickers/components/company-picker.tsx +90 -0
  270. package/blocks/pickers/components/contact-picker.tsx +131 -0
  271. package/blocks/pickers/components/member-picker.tsx +99 -0
  272. package/blocks/pickers/components/search-picker.tsx +98 -0
  273. package/blocks/pickers/hooks/use-current-member.ts +104 -0
  274. package/blocks/pickers/hooks/use-picker-pages.ts +73 -0
  275. package/blocks/pickers/lib/use-debounced.ts +13 -0
  276. package/blocks/quotes/README.md +13 -0
  277. package/blocks/quotes/block.json +48 -1
  278. package/blocks/quotes/components/create-quote-from-deal.tsx +48 -0
  279. package/blocks/quotes/components/quote-builder.tsx +1 -1
  280. package/blocks/quotes/components/quote-lifecycle-actions.tsx +146 -0
  281. package/blocks/quotes/components/quote-list.tsx +5 -3
  282. package/blocks/quotes/components/quote-related.tsx +3 -2
  283. package/blocks/quotes/components/quote-viewer.tsx +7 -2
  284. package/blocks/quotes/components/record-quotes-tab.tsx +90 -0
  285. package/blocks/radar/components/competitor-battle-card.tsx +1 -1
  286. package/blocks/radar/components/radar-overview.tsx +4 -4
  287. package/blocks/radar/components/radar-screen.tsx +2 -2
  288. package/blocks/sequencer/README.md +6 -0
  289. package/blocks/sequencer/block.json +28 -1
  290. package/blocks/sequencer/components/add-to-sequence-button.tsx +82 -0
  291. package/blocks/sequencer/components/enroll-dialog.tsx +2 -2
  292. package/blocks/sequencer/components/record-sequences-tab.tsx +126 -0
  293. package/blocks/sequencer/components/sequence-builder.tsx +19 -20
  294. package/blocks/sequencer/components/sequence-detail.tsx +4 -2
  295. package/blocks/sequencer/components/sequence-enrollments.tsx +4 -2
  296. package/blocks/sequencer/components/sequence-list.tsx +1 -1
  297. package/blocks/sequencer/components/sequence-stats.tsx +8 -8
  298. package/blocks/sequencer/components/sequences-screen.tsx +3 -0
  299. package/blocks/sequencer/components/step-editor.tsx +11 -11
  300. package/blocks/sequencer/lib/sequencer-utils.ts +5 -5
  301. package/blocks/social-ads/README.md +8 -0
  302. package/blocks/social-ads/block.json +137 -4
  303. package/blocks/social-ads/components/audience-sync-detail.tsx +9 -3
  304. package/blocks/social-ads/components/audience-sync.tsx +6 -2
  305. package/blocks/social-ads/components/campaign-ads.tsx +166 -0
  306. package/blocks/social-ads/components/campaign-detail.tsx +6 -1
  307. package/blocks/social-ads/components/campaign-editor.tsx +134 -0
  308. package/blocks/social-ads/components/creative-concepts.tsx +74 -0
  309. package/blocks/social-ads/components/creative-detail.tsx +6 -1
  310. package/blocks/social-ads/components/creative-gallery.tsx +20 -2
  311. package/blocks/social-ads/components/creative-revisions.tsx +57 -0
  312. package/blocks/social-ads/components/creative-tools.tsx +176 -0
  313. package/blocks/social-ads/components/post-composer.tsx +4 -2
  314. package/blocks/social-ads/components/post-detail.tsx +3 -0
  315. package/blocks/social-ads/components/social-ideas.tsx +64 -0
  316. package/blocks/social-ads/components/social-performance.tsx +80 -0
  317. package/blocks/social-ads/components/social-screen.tsx +33 -6
  318. package/blocks/social-ads/lib/ads-extra.ts +67 -0
  319. package/blocks/surveys/README.md +91 -0
  320. package/blocks/surveys/block.json +299 -0
  321. package/blocks/surveys/components/account-nps.tsx +69 -0
  322. package/blocks/surveys/components/contact-survey-history.tsx +52 -0
  323. package/blocks/surveys/components/org-summary.tsx +82 -0
  324. package/blocks/surveys/components/sending-domains.tsx +113 -0
  325. package/blocks/surveys/components/survey-form.tsx +126 -0
  326. package/blocks/surveys/components/survey-responses.tsx +145 -0
  327. package/blocks/surveys/components/survey-results.tsx +72 -0
  328. package/blocks/surveys/components/survey-send-history.tsx +58 -0
  329. package/blocks/surveys/components/survey-send.tsx +162 -0
  330. package/blocks/surveys/components/survey-triggers.tsx +166 -0
  331. package/blocks/surveys/components/surveys-screen.tsx +234 -0
  332. package/blocks/surveys/lib/surveys-types.ts +228 -0
  333. package/blocks/surveys/recipes/create-an-nps-survey.ts +22 -0
  334. package/blocks/surveys/recipes/send-a-survey-and-follow-it.ts +27 -0
  335. package/blocks/surveys/recipes/survey-score-report.ts +27 -0
  336. package/blocks/visitors/components/snippet-install.tsx +18 -9
  337. package/blocks/visitors/components/traffic-chart.tsx +4 -4
  338. package/blocks/visitors/components/visitor-company-card.tsx +24 -14
  339. package/blocks/visitors/components/visitor-feed.tsx +5 -5
  340. package/blocks/webchat/components/chat-widget-config.tsx +1 -1
  341. package/blocks/webchat/components/conversation-list.tsx +1 -1
  342. package/blocks/workbench/components/column-recipe-editor.tsx +1 -1
  343. package/blocks/workbench/components/run-progress.tsx +1 -1
  344. package/blocks/workbench/components/workbench-grid.tsx +1 -1
  345. package/blocks/workbench/components/workbench-screen.tsx +15 -5
  346. package/blocks/workbench/components/workbench-table-list.tsx +14 -2
  347. package/blocks/workflows/components/workflow-editor.tsx +1 -1
  348. package/dist/cli.js +536 -392
  349. package/dist/index.browser.js +1 -1
  350. package/dist/index.browser.js.map +1 -1
  351. package/dist/index.browser.mjs +1 -1
  352. package/dist/index.browser.mjs.map +1 -1
  353. package/dist/index.d.mts +2 -2
  354. package/dist/index.d.ts +2 -2
  355. package/dist/index.js +1 -1
  356. package/dist/index.js.map +1 -1
  357. package/dist/index.mjs +1 -1
  358. package/dist/index.mjs.map +1 -1
  359. package/dist/react.browser.js +1 -1
  360. package/dist/react.browser.js.map +1 -1
  361. package/dist/react.browser.mjs +1 -1
  362. package/dist/react.browser.mjs.map +1 -1
  363. package/dist/react.d.mts +2 -2
  364. package/dist/react.d.ts +2 -2
  365. package/dist/react.js +1 -1
  366. package/dist/react.js.map +1 -1
  367. package/dist/react.mjs +1 -1
  368. package/dist/react.mjs.map +1 -1
  369. package/dist/types/blocks/brand.d.ts +11 -2
  370. package/dist/types/blocks/create.d.ts +7 -3
  371. package/dist/types/blocks/doctor.d.ts +1 -0
  372. package/dist/types/blocks/flows.d.ts +7 -1
  373. package/dist/types/blocks/orgBrand.d.ts +34 -0
  374. package/dist/types/cli.d.ts +3 -0
  375. package/dist/types/version.d.ts +2 -2
  376. package/docs/api/desk.d.ts +2 -2
  377. package/docs/api/desk.md +3 -3
  378. package/package.json +1 -1
  379. package/stacks/6sense/pages/companies.tsx.tmpl +21 -0
  380. package/stacks/6sense/pages/contacts.tsx.tmpl +19 -0
  381. package/stacks/6sense/pages/tasks.tsx.tmpl +19 -0
  382. package/stacks/6sense.json +17 -4
  383. package/stacks/apollo/pages/calls.tsx.tmpl +23 -0
  384. package/stacks/apollo/pages/companies.tsx.tmpl +19 -36
  385. package/stacks/apollo/pages/contacts.tsx.tmpl +29 -95
  386. package/stacks/apollo/pages/deals.tsx.tmpl +17 -0
  387. package/stacks/apollo/pages/inbox-contact.tsx.tmpl +13 -0
  388. package/stacks/apollo/pages/lists.tsx.tmpl +12 -0
  389. package/stacks/apollo/pages/meetings.tsx.tmpl +13 -0
  390. package/stacks/apollo/pages/sequences.tsx.tmpl +12 -0
  391. package/stacks/apollo/pages/tasks.tsx.tmpl +20 -0
  392. package/stacks/apollo.json +36 -8
  393. package/stacks/calendly/pages/companies.tsx.tmpl +19 -0
  394. package/stacks/calendly/pages/contacts.tsx.tmpl +21 -0
  395. package/stacks/calendly/pages/meetings.tsx.tmpl +13 -0
  396. package/stacks/calendly/pages/tasks.tsx.tmpl +19 -0
  397. package/stacks/calendly.json +8 -4
  398. package/stacks/clay/pages/companies.tsx.tmpl +17 -1
  399. package/stacks/clay/pages/contacts.tsx.tmpl +12 -0
  400. package/stacks/clay/pages/lists.tsx.tmpl +12 -0
  401. package/stacks/clay/pages/tasks.tsx.tmpl +19 -0
  402. package/stacks/clay.json +16 -3
  403. package/stacks/gong/pages/calls.tsx.tmpl +23 -0
  404. package/stacks/gong/pages/companies.tsx.tmpl +22 -0
  405. package/stacks/gong/pages/contacts.tsx.tmpl +32 -0
  406. package/stacks/gong/pages/lists.tsx.tmpl +12 -0
  407. package/stacks/gong/pages/meetings.tsx.tmpl +13 -0
  408. package/stacks/gong/pages/tasks.tsx.tmpl +19 -0
  409. package/stacks/gong.json +23 -6
  410. package/stacks/hootsuite/pages/companies.tsx.tmpl +22 -0
  411. package/stacks/hootsuite/pages/contacts.tsx.tmpl +28 -0
  412. package/stacks/hootsuite/pages/lists.tsx.tmpl +12 -0
  413. package/stacks/hootsuite/pages/tasks.tsx.tmpl +19 -0
  414. package/stacks/hootsuite.json +9 -4
  415. package/stacks/hubspot/pages/companies.tsx.tmpl +14 -35
  416. package/stacks/hubspot/pages/contacts.tsx.tmpl +29 -95
  417. package/stacks/hubspot/pages/deals.tsx.tmpl +10 -1
  418. package/stacks/hubspot/pages/inbox.tsx.tmpl +12 -1
  419. package/stacks/hubspot/pages/lifecycle.tsx.tmpl +23 -0
  420. package/stacks/hubspot/pages/lists.tsx.tmpl +12 -0
  421. package/stacks/hubspot/pages/meetings.tsx.tmpl +13 -0
  422. package/stacks/hubspot/pages/sequences.tsx.tmpl +12 -0
  423. package/stacks/hubspot/pages/tasks.tsx.tmpl +20 -0
  424. package/stacks/hubspot.json +21 -5
  425. package/stacks/intercom/pages/companies.tsx.tmpl +19 -0
  426. package/stacks/intercom/pages/contacts.tsx.tmpl +21 -0
  427. package/stacks/intercom/pages/inbox-contact.tsx.tmpl +13 -0
  428. package/stacks/intercom/pages/tasks.tsx.tmpl +19 -0
  429. package/stacks/intercom.json +8 -4
  430. package/stacks/mailchimp/pages/companies.tsx.tmpl +22 -0
  431. package/stacks/mailchimp/pages/contacts.tsx.tmpl +28 -0
  432. package/stacks/mailchimp/pages/lists.tsx.tmpl +12 -0
  433. package/stacks/mailchimp/pages/tasks.tsx.tmpl +19 -0
  434. package/stacks/mailchimp.json +20 -5
  435. package/stacks/outreach/pages/calls.tsx.tmpl +23 -0
  436. package/stacks/outreach/pages/companies.tsx.tmpl +22 -0
  437. package/stacks/outreach/pages/contacts.tsx.tmpl +27 -66
  438. package/stacks/outreach/pages/inbox-contact.tsx.tmpl +13 -0
  439. package/stacks/outreach/pages/lists.tsx.tmpl +12 -0
  440. package/stacks/outreach/pages/meetings.tsx.tmpl +13 -0
  441. package/stacks/outreach/pages/sequences.tsx.tmpl +12 -0
  442. package/stacks/outreach/pages/tasks.tsx.tmpl +19 -0
  443. package/stacks/outreach.json +25 -7
  444. package/stacks/pipedrive/pages/companies.tsx.tmpl +11 -35
  445. package/stacks/pipedrive/pages/contacts.tsx.tmpl +15 -35
  446. package/stacks/pipedrive/pages/deals.tsx.tmpl +10 -1
  447. package/stacks/pipedrive/pages/inbox.tsx.tmpl +12 -1
  448. package/stacks/pipedrive/pages/meetings.tsx.tmpl +13 -0
  449. package/stacks/pipedrive/pages/tasks.tsx.tmpl +20 -0
  450. package/stacks/pipedrive.json +4 -2
  451. package/stacks/salesforce/pages/companies.tsx.tmpl +14 -35
  452. package/stacks/salesforce/pages/contacts.tsx.tmpl +20 -35
  453. package/stacks/salesforce/pages/deals.tsx.tmpl +10 -1
  454. package/stacks/salesforce/pages/lifecycle.tsx.tmpl +23 -0
  455. package/stacks/salesforce/pages/lists.tsx.tmpl +12 -0
  456. package/stacks/salesforce/pages/tasks.tsx.tmpl +20 -0
  457. package/stacks/salesforce.json +7 -3
  458. package/stacks/zoominfo/pages/companies.tsx.tmpl +17 -1
  459. package/stacks/zoominfo/pages/contacts.tsx.tmpl +12 -0
  460. package/stacks/zoominfo/pages/lists.tsx.tmpl +12 -0
  461. package/stacks/zoominfo/pages/tasks.tsx.tmpl +19 -0
  462. package/stacks/zoominfo.json +16 -3
  463. package/styles/styles.css +1 -1
  464. package/templates/next-app/app/globals.css.tmpl +349 -64
  465. package/templates/next-app/components/app-shell.tsx.tmpl +6 -0
  466. package/templates/next-app/components/shell/quick-jump.tsx.tmpl +4 -0
@@ -0,0 +1,19 @@
1
+ "use client";
2
+
3
+ // Generated by `graph8-sdk create {{stackId}}`. The {{block}} block's {{component}} (source in {{blockDir}}), with the
4
+ // other blocks of this app plugged into its slots. Edit freely: this file is yours.
5
+ import { CompaniesScreen } from "@/components/g8/crm/companies-screen";
6
+ import { RecordEngagementTab } from "@/components/g8/crm/record-engagement-tab";
7
+ import { useRouter } from "next/navigation";
8
+
9
+ export default function Page() {
10
+ const router = useRouter();
11
+ return (
12
+ <CompaniesScreen
13
+ onOpenContact={(contact) => router.push(`/contacts?id=${contact.id}`)}
14
+ extraDetailTabs={[
15
+ { id: "engagement", label: "Engagement", render: (c) => <RecordEngagementTab kind="companies" id={c.id} /> },
16
+ ]}
17
+ />
18
+ );
19
+ }
@@ -0,0 +1,21 @@
1
+ "use client";
2
+
3
+ // Generated by `graph8-sdk create {{stackId}}`. The {{block}} block's {{component}} (source in {{blockDir}}), with the
4
+ // other blocks of this app plugged into its slots. Edit freely: this file is yours.
5
+ import { ContactsScreen } from "@/components/g8/crm/contacts-screen";
6
+ import { RecordEngagementTab } from "@/components/g8/crm/record-engagement-tab";
7
+ import { RecordConversationsTab } from "@/components/g8/inbox/record-conversations-tab";
8
+ import { useRouter } from "next/navigation";
9
+
10
+ export default function Page() {
11
+ const router = useRouter();
12
+ return (
13
+ <ContactsScreen
14
+ onOpenCompany={(id) => router.push(`/companies?id=${id}`)}
15
+ extraDetailTabs={[
16
+ { id: "conversations", label: "Conversations", render: (c) => <RecordConversationsTab email={c.work_email} alsoEmails={[c.personal_emails]} onOpenThread={(sel) => router.push(`/inbox?id=${encodeURIComponent(sel)}`)} /> },
17
+ { id: "engagement", label: "Engagement", render: (c) => <RecordEngagementTab kind="contacts" id={c.id} /> },
18
+ ]}
19
+ />
20
+ );
21
+ }
@@ -0,0 +1,13 @@
1
+ "use client";
2
+
3
+ // Generated by `graph8-sdk create {{stackId}}`. The {{block}} block's {{component}} (source in {{blockDir}}), with the
4
+ // other blocks of this app plugged into its slots. Edit freely: this file is yours.
5
+ import { useRouter } from "next/navigation";
6
+ import { ContactLookupLink } from "@/components/g8/crm/contact-lookup-link";
7
+ import { InboxScreen } from "@/components/g8/inbox/inbox-screen";
8
+
9
+ /** A conversation opens the sender when they are a contact in your CRM. */
10
+ export default function Page() {
11
+ const router = useRouter();
12
+ return <InboxScreen renderDetailActions={(thread) => <ContactLookupLink email={thread.contact?.email} onOpen={(id) => router.push(`/contacts?id=${id}`)} />} />;
13
+ }
@@ -0,0 +1,19 @@
1
+ "use client";
2
+
3
+ // Generated by `graph8-sdk create {{stackId}}`. The {{block}} block's {{component}} (source in {{blockDir}}), with the
4
+ // other blocks of this app plugged into its slots. Edit freely: this file is yours.
5
+ import { useRouter } from "next/navigation";
6
+ import { TasksScreen } from "@/components/g8/crm/tasks-screen";
7
+
8
+ /** A task's linked record opens in the screen that owns it. */
9
+ export default function Page() {
10
+ const router = useRouter();
11
+ return (
12
+ <TasksScreen
13
+ onOpenRecord={(record) => {
14
+ if (record.entity_type === "contact") router.push(`/contacts?id=${encodeURIComponent(record.entity_id)}`);
15
+ if (record.entity_type === "company") router.push(`/companies?id=${encodeURIComponent(record.entity_id)}`);
16
+ }}
17
+ />
18
+ );
19
+ }
@@ -21,7 +21,8 @@
21
21
  "component": "InboxScreen",
22
22
  "icon": "Inbox",
23
23
  "group": "Engage",
24
- "description": "Replies from every channel in one place"
24
+ "description": "Replies from every channel in one place",
25
+ "page": "pages/inbox-contact.tsx.tmpl"
25
26
  },
26
27
  {
27
28
  "label": "Conversations",
@@ -39,7 +40,8 @@
39
40
  "component": "ContactsScreen",
40
41
  "icon": "Users",
41
42
  "group": "Prospect",
42
- "description": "People you sell to, with notes, tasks and activity"
43
+ "description": "People you sell to, with notes, tasks and activity",
44
+ "page": "pages/contacts.tsx.tmpl"
43
45
  },
44
46
  {
45
47
  "label": "Companies",
@@ -48,7 +50,8 @@
48
50
  "component": "CompaniesScreen",
49
51
  "icon": "Building2",
50
52
  "group": "Prospect",
51
- "description": "Accounts and the people at them"
53
+ "description": "Accounts and the people at them",
54
+ "page": "pages/companies.tsx.tmpl"
52
55
  },
53
56
  {
54
57
  "label": "Tasks",
@@ -57,7 +60,8 @@
57
60
  "component": "TasksScreen",
58
61
  "icon": "CheckSquare",
59
62
  "group": "Work",
60
- "description": "Follow-ups due across your records"
63
+ "description": "Follow-ups due across your records",
64
+ "page": "pages/tasks.tsx.tmpl"
61
65
  },
62
66
  {
63
67
  "label": "Agents",
@@ -0,0 +1,22 @@
1
+ "use client";
2
+
3
+ // Generated by `graph8-sdk create {{stackId}}`. The {{block}} block's {{component}} (source in {{blockDir}}), with the
4
+ // other blocks of this app plugged into its slots. Edit freely: this file is yours.
5
+ import { CompaniesScreen } from "@/components/g8/crm/companies-screen";
6
+ import { RecordEngagementTab } from "@/components/g8/crm/record-engagement-tab";
7
+ import { AddCompanyPeopleToListButton } from "@/components/g8/lists/add-company-people-to-list-button";
8
+ import { useRouter } from "next/navigation";
9
+
10
+ export default function Page() {
11
+ const router = useRouter();
12
+ return (
13
+ <CompaniesScreen
14
+ onOpenContact={(contact) => router.push(`/contacts?id=${contact.id}`)}
15
+ renderBulkActions={({ ids, clear }) => <AddCompanyPeopleToListButton companyIds={ids} onAdded={clear} />}
16
+ renderDetailActions={(c) => <AddCompanyPeopleToListButton companyIds={[c.id]} />}
17
+ extraDetailTabs={[
18
+ { id: "engagement", label: "Engagement", render: (c) => <RecordEngagementTab kind="companies" id={c.id} /> },
19
+ ]}
20
+ />
21
+ );
22
+ }
@@ -0,0 +1,28 @@
1
+ "use client";
2
+
3
+ // Generated by `graph8-sdk create {{stackId}}`. The {{block}} block's {{component}} (source in {{blockDir}}), with the
4
+ // other blocks of this app plugged into its slots. Edit freely: this file is yours.
5
+ import { ContactsScreen } from "@/components/g8/crm/contacts-screen";
6
+ import { RecordEngagementTab } from "@/components/g8/crm/record-engagement-tab";
7
+ import { AddToListButton } from "@/components/g8/lists/add-to-list-button";
8
+ import { RecordListsTab } from "@/components/g8/lists/record-lists-tab";
9
+ import { useRouter } from "next/navigation";
10
+
11
+ export default function Page() {
12
+ const router = useRouter();
13
+ return (
14
+ <ContactsScreen
15
+ onOpenCompany={(id) => router.push(`/companies?id=${id}`)}
16
+ renderBulkActions={({ ids, clear }) => <AddToListButton contactIds={ids} onAdded={clear} />}
17
+ renderDetailActions={(c) => (
18
+ <>
19
+ <AddToListButton contactIds={[c.id]} />
20
+ </>
21
+ )}
22
+ extraDetailTabs={[
23
+ { id: "lists", label: "Lists", render: (c) => <RecordListsTab contactId={c.id} onOpenList={(id) => router.push(`/lists?id=${id}`)} /> },
24
+ { id: "engagement", label: "Engagement", render: (c) => <RecordEngagementTab kind="contacts" id={c.id} /> },
25
+ ]}
26
+ />
27
+ );
28
+ }
@@ -0,0 +1,12 @@
1
+ "use client";
2
+
3
+ // Generated by `graph8-sdk create {{stackId}}`. The {{block}} block's {{component}} (source in {{blockDir}}), with the
4
+ // other blocks of this app plugged into its slots. Edit freely: this file is yours.
5
+ import { useRouter } from "next/navigation";
6
+ import { ListsScreen } from "@/components/g8/lists/lists-screen";
7
+
8
+ /** A list member opens in Contacts. */
9
+ export default function Page() {
10
+ const router = useRouter();
11
+ return <ListsScreen onOpenContact={(id) => router.push(`/contacts?id=${id}`)} />;
12
+ }
@@ -0,0 +1,19 @@
1
+ "use client";
2
+
3
+ // Generated by `graph8-sdk create {{stackId}}`. The {{block}} block's {{component}} (source in {{blockDir}}), with the
4
+ // other blocks of this app plugged into its slots. Edit freely: this file is yours.
5
+ import { useRouter } from "next/navigation";
6
+ import { TasksScreen } from "@/components/g8/crm/tasks-screen";
7
+
8
+ /** A task's linked record opens in the screen that owns it. */
9
+ export default function Page() {
10
+ const router = useRouter();
11
+ return (
12
+ <TasksScreen
13
+ onOpenRecord={(record) => {
14
+ if (record.entity_type === "contact") router.push(`/contacts?id=${encodeURIComponent(record.entity_id)}`);
15
+ if (record.entity_type === "company") router.push(`/companies?id=${encodeURIComponent(record.entity_id)}`);
16
+ }}
17
+ />
18
+ );
19
+ }
@@ -6,11 +6,13 @@
6
6
  "status": "available",
7
7
  "blocks": [
8
8
  "foundation",
9
+ "pickers",
9
10
  "crm",
10
11
  "forms",
11
12
  "lists",
12
13
  "newsletter",
13
- "nurture"
14
+ "nurture",
15
+ "surveys"
14
16
  ],
15
17
  "home": "/newsletter",
16
18
  "nav": [
@@ -32,6 +34,15 @@
32
34
  "group": "Marketing",
33
35
  "description": "Automated nurture tracks"
34
36
  },
37
+ {
38
+ "label": "Surveys",
39
+ "path": "/surveys",
40
+ "block": "surveys",
41
+ "component": "SurveysScreen",
42
+ "icon": "ClipboardCheck",
43
+ "group": "Marketing",
44
+ "description": "NPS and CSAT: ask, score and read the answers"
45
+ },
35
46
  {
36
47
  "label": "Forms",
37
48
  "path": "/forms",
@@ -48,7 +59,8 @@
48
59
  "component": "ContactsScreen",
49
60
  "icon": "Users",
50
61
  "group": "Prospect",
51
- "description": "People you sell to, with notes, tasks and activity"
62
+ "description": "People you sell to, with notes, tasks and activity",
63
+ "page": "pages/contacts.tsx.tmpl"
52
64
  },
53
65
  {
54
66
  "label": "Companies",
@@ -57,7 +69,8 @@
57
69
  "component": "CompaniesScreen",
58
70
  "icon": "Building2",
59
71
  "group": "Prospect",
60
- "description": "Accounts and the people at them"
72
+ "description": "Accounts and the people at them",
73
+ "page": "pages/companies.tsx.tmpl"
61
74
  },
62
75
  {
63
76
  "label": "Tasks",
@@ -66,7 +79,8 @@
66
79
  "component": "TasksScreen",
67
80
  "icon": "CheckSquare",
68
81
  "group": "Work",
69
- "description": "Follow-ups due across your records"
82
+ "description": "Follow-ups due across your records",
83
+ "page": "pages/tasks.tsx.tmpl"
70
84
  },
71
85
  {
72
86
  "label": "Lists",
@@ -75,7 +89,8 @@
75
89
  "component": "ListsScreen",
76
90
  "icon": "ListChecks",
77
91
  "group": "Prospect",
78
- "description": "Saved audiences you can sequence or sync"
92
+ "description": "Saved audiences you can sequence or sync",
93
+ "page": "pages/lists.tsx.tmpl"
79
94
  },
80
95
  {
81
96
  "label": "Suppressions",
@@ -0,0 +1,23 @@
1
+ "use client";
2
+
3
+ // Generated by `graph8-sdk create {{stackId}}`. The {{block}} block's {{component}} (source in {{blockDir}}), with the
4
+ // other blocks of this app plugged into its slots. Edit freely: this file is yours.
5
+ import { useRouter } from "next/navigation";
6
+ import { Button } from "@graph8/sdk/ui";
7
+ import { UserRound } from "lucide-react";
8
+ import { CallLogScreen } from "@/components/g8/dialer/call-log-screen";
9
+
10
+ /** A call opens the person it was made to. */
11
+ export default function Page() {
12
+ const router = useRouter();
13
+ return (
14
+ <CallLogScreen
15
+ renderDetailActions={(call) => call.contact_id ? (
16
+ <Button size="sm" variant="outline" onClick={() => router.push(`/contacts?id=${encodeURIComponent(call.contact_id as string)}`)}>
17
+ <UserRound className="mr-1 size-4" aria-hidden />
18
+ Open contact
19
+ </Button>
20
+ ) : null}
21
+ />
22
+ );
23
+ }
@@ -0,0 +1,22 @@
1
+ "use client";
2
+
3
+ // Generated by `graph8-sdk create {{stackId}}`. The {{block}} block's {{component}} (source in {{blockDir}}), with the
4
+ // other blocks of this app plugged into its slots. Edit freely: this file is yours.
5
+ import { CompaniesScreen } from "@/components/g8/crm/companies-screen";
6
+ import { RecordEngagementTab } from "@/components/g8/crm/record-engagement-tab";
7
+ import { AddCompanyPeopleToListButton } from "@/components/g8/lists/add-company-people-to-list-button";
8
+ import { useRouter } from "next/navigation";
9
+
10
+ export default function Page() {
11
+ const router = useRouter();
12
+ return (
13
+ <CompaniesScreen
14
+ onOpenContact={(contact) => router.push(`/contacts?id=${contact.id}`)}
15
+ renderBulkActions={({ ids, clear }) => <AddCompanyPeopleToListButton companyIds={ids} onAdded={clear} />}
16
+ renderDetailActions={(c) => <AddCompanyPeopleToListButton companyIds={[c.id]} />}
17
+ extraDetailTabs={[
18
+ { id: "engagement", label: "Engagement", render: (c) => <RecordEngagementTab kind="companies" id={c.id} /> },
19
+ ]}
20
+ />
21
+ );
22
+ }
@@ -2,84 +2,45 @@
2
2
 
3
3
  // Generated by `graph8-sdk create {{stackId}}`. The {{block}} block's {{component}} (source in {{blockDir}}), with the
4
4
  // other blocks of this app plugged into its slots. Edit freely: this file is yours.
5
- import { useState } from "react";
6
- import { Button, Sheet, SheetContent, SheetDescription, SheetHeader, SheetTitle, Skeleton } from "@graph8/sdk/ui";
7
- import { ListPlus } from "lucide-react";
8
- import { ApiError } from "@/components/g8/_foundation/api-error";
9
- import { EmptyState } from "@/components/g8/_foundation/empty-state";
10
- import { useG8Query } from "@/components/g8/_foundation/hooks/use-g8-query";
11
- import { g8Get } from "@/components/g8/_foundation/lib/g8-client";
5
+ import { RecordMeetingsTab } from "@/components/g8/appointments/record-meetings-tab";
12
6
  import { ContactsScreen } from "@/components/g8/crm/contacts-screen";
7
+ import { RecordEngagementTab } from "@/components/g8/crm/record-engagement-tab";
13
8
  import { CallContactButton } from "@/components/g8/dialer/call-contact-button";
14
- import { EnrollDialog } from "@/components/g8/sequencer/enroll-dialog";
15
- import { listOf, statusGroup, type SequenceRow } from "@/components/g8/sequencer/lib/sequencer-utils";
16
-
17
- /** Every active sequence, paging through the whole list (the API answers one page at a time). */
18
- async function activeSequences(signal: AbortSignal): Promise<SequenceRow[]> {
19
- const out: SequenceRow[] = [];
20
- for (let page = 1; page <= 50; page++) {
21
- const env = await g8Get("/sequences", { page, limit: 100 }, { signal });
22
- const rows = listOf<SequenceRow>(env);
23
- out.push(...rows.filter((s) => statusGroup(s.status) === "live"));
24
- const more = (env as { pagination?: { has_next?: boolean } }).pagination?.has_next;
25
- if (!more || rows.length === 0) break;
26
- }
27
- return out;
28
- }
29
-
30
- /** Pick a sequence, then enroll the contacts in it. The enroll dialog shows the sending preflight before anything is sent. */
31
- function AddToSequence({ contactIds, onEnrolled, variant = "outline" }: { contactIds: number[]; onEnrolled?: () => void; variant?: "outline" | "default" }) {
32
- const [step, setStep] = useState<"closed" | "pick" | "enroll">("closed");
33
- const [sequenceId, setSequenceId] = useState("");
34
- const sequences = useG8Query(activeSequences, [], { enabled: step === "pick" });
35
- const chosen = (sequences.data ?? []).find((s) => s.id === sequenceId);
36
- return (
37
- <>
38
- <Button size="sm" variant={variant} disabled={contactIds.length === 0} onClick={() => { setSequenceId(""); setStep("pick"); }}>
39
- <ListPlus className="mr-1 size-4" aria-hidden />
40
- Add to sequence
41
- </Button>
42
- <Sheet open={step === "pick"} onOpenChange={(o) => { if (!o) setStep("closed"); }}>
43
- <SheetContent className="w-full sm:max-w-md">
44
- <SheetHeader>
45
- <SheetTitle>Add to sequence</SheetTitle>
46
- <SheetDescription>{contactIds.length === 1 ? "1 contact" : `${contactIds.length} contacts`} will be enrolled in the sequence you pick.</SheetDescription>
47
- </SheetHeader>
48
- <div className="space-y-3 p-4">
49
- {sequences.error ? <ApiError error={sequences.error} title="Could not load sequences" onRetry={() => void sequences.refetch()} /> : null}
50
- {sequences.loading && !sequences.data ? <Skeleton className="h-9 w-full" aria-label="Loading sequences" /> : null}
51
- {sequences.data && sequences.data.length === 0 ? <EmptyState compact title="No active sequences" description="Launch a sequence on the Sequences page first." /> : null}
52
- {sequences.data && sequences.data.length > 0 ? (
53
- <>
54
- <label htmlFor="enroll-sequence" className="text-sm font-medium">Sequence</label>
55
- <select id="enroll-sequence" className="h-9 w-full rounded-md border bg-background px-2 text-sm" value={sequenceId} onChange={(e) => setSequenceId(e.target.value)}>
56
- <option value="">Choose a sequence</option>
57
- {sequences.data.map((s) => <option key={s.id} value={s.id}>{s.name || s.id}</option>)}
58
- </select>
59
- <Button disabled={!sequenceId} onClick={() => setStep("enroll")}>Continue</Button>
60
- </>
61
- ) : null}
62
- </div>
63
- </SheetContent>
64
- </Sheet>
65
- {step === "enroll" && chosen ? (
66
- <EnrollDialog open sequenceId={chosen.id} sequenceName={chosen.name ?? undefined} contactIds={contactIds} onClose={() => setStep("closed")} onEnrolled={() => { setStep("closed"); onEnrolled?.(); }} />
67
- ) : null}
68
- </>
69
- );
70
- }
9
+ import { RecordCallsTab } from "@/components/g8/dialer/record-calls-tab";
10
+ import { RecordConversationsTab } from "@/components/g8/inbox/record-conversations-tab";
11
+ import { AddToListButton } from "@/components/g8/lists/add-to-list-button";
12
+ import { RecordListsTab } from "@/components/g8/lists/record-lists-tab";
13
+ import { AddToSequenceButton } from "@/components/g8/sequencer/add-to-sequence-button";
14
+ import { RecordSequencesTab } from "@/components/g8/sequencer/record-sequences-tab";
15
+ import { useRouter } from "next/navigation";
71
16
 
72
17
  export default function Page() {
18
+ const router = useRouter();
73
19
  return (
74
20
  <ContactsScreen
75
- renderBulkActions={({ ids, clear }) => <AddToSequence contactIds={ids} onEnrolled={clear} />}
21
+ onOpenCompany={(id) => router.push(`/companies?id=${id}`)}
22
+ renderBulkActions={({ ids, clear }) => (
23
+ <>
24
+ <AddToSequenceButton contactIds={ids} onEnrolled={clear} />
25
+ <AddToListButton contactIds={ids} onAdded={clear} />
26
+ </>
27
+ )}
76
28
  renderDetailActions={(c) => (
77
29
  <>
78
- <AddToSequence contactIds={[c.id]} />
30
+ <AddToSequenceButton contactIds={[c.id]} />
31
+ <AddToListButton contactIds={[c.id]} />
79
32
  {/* One call to this contact through the dialer; confirmed, and your softphone joins it. */}
80
33
  <CallContactButton contact={{ id: c.id, first_name: c.first_name, last_name: c.last_name, full_name: c.full_name, email: c.work_email, company: c.company_name, mobile_phone: c.mobile_phone, direct_phone: c.direct_phone }} />
81
34
  </>
82
35
  )}
36
+ extraDetailTabs={[
37
+ { id: "lists", label: "Lists", render: (c) => <RecordListsTab contactId={c.id} onOpenList={(id) => router.push(`/lists?id=${id}`)} /> },
38
+ { id: "sequences", label: "Sequences", render: (c) => <RecordSequencesTab contactId={c.id} onOpenSequence={(id) => router.push(`/sequences?id=${encodeURIComponent(id)}`)} /> },
39
+ { id: "meetings", label: "Meetings", render: (c) => <RecordMeetingsTab contactId={c.id} onOpenMeeting={(sel) => router.push(`/meetings?sel=${encodeURIComponent(sel)}`)} /> },
40
+ { id: "calls", label: "Calls", render: (c) => <RecordCallsTab contact={{ id: c.id, first_name: c.first_name, last_name: c.last_name, full_name: c.full_name, email: c.work_email, company: c.company_name, mobile_phone: c.mobile_phone, direct_phone: c.direct_phone }} onOpenCall={(room) => router.push(`/calls?id=${encodeURIComponent(room)}`)} /> },
41
+ { id: "conversations", label: "Conversations", render: (c) => <RecordConversationsTab email={c.work_email} alsoEmails={[c.personal_emails]} onOpenThread={(sel) => router.push(`/inbox?id=${encodeURIComponent(sel)}`)} /> },
42
+ { id: "engagement", label: "Engagement", render: (c) => <RecordEngagementTab kind="contacts" id={c.id} /> },
43
+ ]}
83
44
  />
84
45
  );
85
46
  }
@@ -0,0 +1,13 @@
1
+ "use client";
2
+
3
+ // Generated by `graph8-sdk create {{stackId}}`. The {{block}} block's {{component}} (source in {{blockDir}}), with the
4
+ // other blocks of this app plugged into its slots. Edit freely: this file is yours.
5
+ import { useRouter } from "next/navigation";
6
+ import { ContactLookupLink } from "@/components/g8/crm/contact-lookup-link";
7
+ import { InboxScreen } from "@/components/g8/inbox/inbox-screen";
8
+
9
+ /** A conversation opens the sender when they are a contact in your CRM. */
10
+ export default function Page() {
11
+ const router = useRouter();
12
+ return <InboxScreen renderDetailActions={(thread) => <ContactLookupLink email={thread.contact?.email} onOpen={(id) => router.push(`/contacts?id=${id}`)} />} />;
13
+ }
@@ -0,0 +1,12 @@
1
+ "use client";
2
+
3
+ // Generated by `graph8-sdk create {{stackId}}`. The {{block}} block's {{component}} (source in {{blockDir}}), with the
4
+ // other blocks of this app plugged into its slots. Edit freely: this file is yours.
5
+ import { useRouter } from "next/navigation";
6
+ import { ListsScreen } from "@/components/g8/lists/lists-screen";
7
+
8
+ /** A list member opens in Contacts. */
9
+ export default function Page() {
10
+ const router = useRouter();
11
+ return <ListsScreen onOpenContact={(id) => router.push(`/contacts?id=${id}`)} />;
12
+ }
@@ -0,0 +1,13 @@
1
+ "use client";
2
+
3
+ // Generated by `graph8-sdk create {{stackId}}`. The {{block}} block's {{component}} (source in {{blockDir}}), with the
4
+ // other blocks of this app plugged into its slots. Edit freely: this file is yours.
5
+ import { useRouter } from "next/navigation";
6
+ import { MeetingContactLinks } from "@/components/g8/appointments/meeting-contact-links";
7
+ import { MeetingsScreen } from "@/components/g8/appointments/meetings-screen";
8
+
9
+ /** A meeting opens the attendees who are contacts in your CRM. */
10
+ export default function Page() {
11
+ const router = useRouter();
12
+ return <MeetingsScreen renderDetailActions={(selection) => <MeetingContactLinks selection={selection} onOpenContact={(id) => router.push(`/contacts?id=${id}`)} />} />;
13
+ }
@@ -0,0 +1,12 @@
1
+ "use client";
2
+
3
+ // Generated by `graph8-sdk create {{stackId}}`. The {{block}} block's {{component}} (source in {{blockDir}}), with the
4
+ // other blocks of this app plugged into its slots. Edit freely: this file is yours.
5
+ import { useRouter } from "next/navigation";
6
+ import { SequencesScreen } from "@/components/g8/sequencer/sequences-screen";
7
+
8
+ /** An enrolled person opens in Contacts. */
9
+ export default function Page() {
10
+ const router = useRouter();
11
+ return <SequencesScreen onOpenContact={(id) => router.push(`/contacts?id=${id}`)} />;
12
+ }
@@ -0,0 +1,19 @@
1
+ "use client";
2
+
3
+ // Generated by `graph8-sdk create {{stackId}}`. The {{block}} block's {{component}} (source in {{blockDir}}), with the
4
+ // other blocks of this app plugged into its slots. Edit freely: this file is yours.
5
+ import { useRouter } from "next/navigation";
6
+ import { TasksScreen } from "@/components/g8/crm/tasks-screen";
7
+
8
+ /** A task's linked record opens in the screen that owns it. */
9
+ export default function Page() {
10
+ const router = useRouter();
11
+ return (
12
+ <TasksScreen
13
+ onOpenRecord={(record) => {
14
+ if (record.entity_type === "contact") router.push(`/contacts?id=${encodeURIComponent(record.entity_id)}`);
15
+ if (record.entity_type === "company") router.push(`/companies?id=${encodeURIComponent(record.entity_id)}`);
16
+ }}
17
+ />
18
+ );
19
+ }
@@ -6,6 +6,7 @@
6
6
  "status": "available",
7
7
  "blocks": [
8
8
  "foundation",
9
+ "pickers",
9
10
  "crm",
10
11
  "lists",
11
12
  "mailboxes",
@@ -13,6 +14,7 @@
13
14
  "campaigns",
14
15
  "inbox",
15
16
  "dialer",
17
+ "phone-numbers",
16
18
  "appointments",
17
19
  "analytics"
18
20
  ],
@@ -44,7 +46,8 @@
44
46
  "component": "CompaniesScreen",
45
47
  "icon": "Building2",
46
48
  "group": "Prospect",
47
- "description": "Accounts and the people at them"
49
+ "description": "Accounts and the people at them",
50
+ "page": "pages/companies.tsx.tmpl"
48
51
  },
49
52
  {
50
53
  "label": "Lists",
@@ -53,7 +56,8 @@
53
56
  "component": "ListsScreen",
54
57
  "icon": "ListChecks",
55
58
  "group": "Prospect",
56
- "description": "Saved audiences you can sequence or sync"
59
+ "description": "Saved audiences you can sequence or sync",
60
+ "page": "pages/lists.tsx.tmpl"
57
61
  },
58
62
  {
59
63
  "label": "Sequences",
@@ -62,7 +66,8 @@
62
66
  "component": "SequencesScreen",
63
67
  "icon": "Workflow",
64
68
  "group": "Engage",
65
- "description": "Multi-step outreach cadences"
69
+ "description": "Multi-step outreach cadences",
70
+ "page": "pages/sequences.tsx.tmpl"
66
71
  },
67
72
  {
68
73
  "label": "Campaigns",
@@ -80,7 +85,8 @@
80
85
  "component": "InboxScreen",
81
86
  "icon": "Inbox",
82
87
  "group": "Engage",
83
- "description": "Replies from every channel in one place"
88
+ "description": "Replies from every channel in one place",
89
+ "page": "pages/inbox-contact.tsx.tmpl"
84
90
  },
85
91
  {
86
92
  "label": "Dialer",
@@ -98,7 +104,8 @@
98
104
  "component": "CallLogScreen",
99
105
  "icon": "PhoneCall",
100
106
  "group": "Engage",
101
- "description": "Every call with transcript and outcome"
107
+ "description": "Every call with transcript and outcome",
108
+ "page": "pages/calls.tsx.tmpl"
102
109
  },
103
110
  {
104
111
  "label": "Meetings",
@@ -107,7 +114,8 @@
107
114
  "component": "MeetingsScreen",
108
115
  "icon": "CalendarCheck",
109
116
  "group": "Engage",
110
- "description": "Booked, held and missed meetings"
117
+ "description": "Booked, held and missed meetings",
118
+ "page": "pages/meetings.tsx.tmpl"
111
119
  },
112
120
  {
113
121
  "label": "Scheduling",
@@ -125,7 +133,8 @@
125
133
  "component": "TasksScreen",
126
134
  "icon": "CheckSquare",
127
135
  "group": "Work",
128
- "description": "Follow-ups due across your records"
136
+ "description": "Follow-ups due across your records",
137
+ "page": "pages/tasks.tsx.tmpl"
129
138
  },
130
139
  {
131
140
  "label": "Mailboxes",
@@ -136,6 +145,15 @@
136
145
  "group": "Setup",
137
146
  "description": "Sending mailboxes and warmup health"
138
147
  },
148
+ {
149
+ "label": "Phone numbers",
150
+ "path": "/phone-numbers",
151
+ "block": "phone-numbers",
152
+ "component": "PhoneNumbersScreen",
153
+ "icon": "Phone",
154
+ "group": "Setup",
155
+ "description": "Numbers to call and text from: buy, assign and release"
156
+ },
139
157
  {
140
158
  "label": "Suppressions",
141
159
  "path": "/suppressions",