@aglyn/plugins-outreach 1.0.0-beta.143

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (282) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +93 -0
  3. package/package.json +52 -0
  4. package/src/index.d.ts +22 -0
  5. package/src/index.js +29 -0
  6. package/src/index.js.map +1 -0
  7. package/src/lib/components/compliance-section.d.ts +20 -0
  8. package/src/lib/components/compliance-section.js +291 -0
  9. package/src/lib/components/compliance-section.js.map +1 -0
  10. package/src/lib/components/enroll-dialog.d.ts +36 -0
  11. package/src/lib/components/enroll-dialog.js +656 -0
  12. package/src/lib/components/enroll-dialog.js.map +1 -0
  13. package/src/lib/components/enrollments-table.d.ts +28 -0
  14. package/src/lib/components/enrollments-table.js +375 -0
  15. package/src/lib/components/enrollments-table.js.map +1 -0
  16. package/src/lib/components/mailbox-card.d.ts +46 -0
  17. package/src/lib/components/mailbox-card.js +517 -0
  18. package/src/lib/components/mailbox-card.js.map +1 -0
  19. package/src/lib/components/mailboxes-section.d.ts +24 -0
  20. package/src/lib/components/mailboxes-section.js +258 -0
  21. package/src/lib/components/mailboxes-section.js.map +1 -0
  22. package/src/lib/components/outreach-console-page.d.ts +17 -0
  23. package/src/lib/components/outreach-console-page.js +81 -0
  24. package/src/lib/components/outreach-console-page.js.map +1 -0
  25. package/src/lib/components/outreach-console-sections.d.ts +43 -0
  26. package/src/lib/components/outreach-console-sections.js +55 -0
  27. package/src/lib/components/outreach-console-sections.js.map +1 -0
  28. package/src/lib/components/outreach-ui.d.ts +51 -0
  29. package/src/lib/components/outreach-ui.js +171 -0
  30. package/src/lib/components/outreach-ui.js.map +1 -0
  31. package/src/lib/components/send-window-fields.d.ts +25 -0
  32. package/src/lib/components/send-window-fields.js +178 -0
  33. package/src/lib/components/send-window-fields.js.map +1 -0
  34. package/src/lib/components/sequence-detail.d.ts +54 -0
  35. package/src/lib/components/sequence-detail.js +435 -0
  36. package/src/lib/components/sequence-detail.js.map +1 -0
  37. package/src/lib/components/sequence-editor.d.ts +37 -0
  38. package/src/lib/components/sequence-editor.js +485 -0
  39. package/src/lib/components/sequence-editor.js.map +1 -0
  40. package/src/lib/components/sequence-mailbox-picker.d.ts +44 -0
  41. package/src/lib/components/sequence-mailbox-picker.js +137 -0
  42. package/src/lib/components/sequence-mailbox-picker.js.map +1 -0
  43. package/src/lib/components/sequence-preview.d.ts +27 -0
  44. package/src/lib/components/sequence-preview.js +146 -0
  45. package/src/lib/components/sequence-preview.js.map +1 -0
  46. package/src/lib/components/sequence-step-card.d.ts +31 -0
  47. package/src/lib/components/sequence-step-card.js +326 -0
  48. package/src/lib/components/sequence-step-card.js.map +1 -0
  49. package/src/lib/components/sequences-section.d.ts +40 -0
  50. package/src/lib/components/sequences-section.js +310 -0
  51. package/src/lib/components/sequences-section.js.map +1 -0
  52. package/src/lib/components/use-outreach-api.d.ts +38 -0
  53. package/src/lib/components/use-outreach-api.js +139 -0
  54. package/src/lib/components/use-outreach-api.js.map +1 -0
  55. package/src/lib/components/use-outreach-crm.d.ts +50 -0
  56. package/src/lib/components/use-outreach-crm.js +200 -0
  57. package/src/lib/components/use-outreach-crm.js.map +1 -0
  58. package/src/lib/components/use-outreach-data.d.ts +55 -0
  59. package/src/lib/components/use-outreach-data.js +199 -0
  60. package/src/lib/components/use-outreach-data.js.map +1 -0
  61. package/src/lib/components/use-outreach-mailbox-api.d.ts +30 -0
  62. package/src/lib/components/use-outreach-mailbox-api.js +101 -0
  63. package/src/lib/components/use-outreach-mailbox-api.js.map +1 -0
  64. package/src/lib/components/use-outreach-mailboxes.d.ts +22 -0
  65. package/src/lib/components/use-outreach-mailboxes.js +68 -0
  66. package/src/lib/components/use-outreach-mailboxes.js.map +1 -0
  67. package/src/lib/components/use-outreach-settings.d.ts +17 -0
  68. package/src/lib/components/use-outreach-settings.js +64 -0
  69. package/src/lib/components/use-outreach-settings.js.map +1 -0
  70. package/src/lib/constants/api-routes.d.ts +68 -0
  71. package/src/lib/constants/api-routes.js +57 -0
  72. package/src/lib/constants/api-routes.js.map +1 -0
  73. package/src/lib/constants/bundle-common.d.ts +46 -0
  74. package/src/lib/constants/bundle-common.js +55 -0
  75. package/src/lib/constants/bundle-common.js.map +1 -0
  76. package/src/lib/constants/runtime-jobs.d.ts +24 -0
  77. package/src/lib/constants/runtime-jobs.js +24 -0
  78. package/src/lib/constants/runtime-jobs.js.map +1 -0
  79. package/src/lib/declarations.console-server.d.ts +38 -0
  80. package/src/lib/declarations.console-server.js +99 -0
  81. package/src/lib/declarations.console-server.js.map +1 -0
  82. package/src/lib/engine/compose.d.ts +86 -0
  83. package/src/lib/engine/compose.js +212 -0
  84. package/src/lib/engine/compose.js.map +1 -0
  85. package/src/lib/engine/delivery-status.d.ts +53 -0
  86. package/src/lib/engine/delivery-status.js +184 -0
  87. package/src/lib/engine/delivery-status.js.map +1 -0
  88. package/src/lib/engine/do-not-contact.d.ts +18 -0
  89. package/src/lib/engine/do-not-contact.js +34 -0
  90. package/src/lib/engine/do-not-contact.js.map +1 -0
  91. package/src/lib/engine/enrollment-state.d.ts +156 -0
  92. package/src/lib/engine/enrollment-state.js +303 -0
  93. package/src/lib/engine/enrollment-state.js.map +1 -0
  94. package/src/lib/engine/gates.d.ts +125 -0
  95. package/src/lib/engine/gates.js +232 -0
  96. package/src/lib/engine/gates.js.map +1 -0
  97. package/src/lib/engine/index.d.ts +28 -0
  98. package/src/lib/engine/index.js +33 -0
  99. package/src/lib/engine/index.js.map +1 -0
  100. package/src/lib/engine/mailbox-health.d.ts +49 -0
  101. package/src/lib/engine/mailbox-health.js +83 -0
  102. package/src/lib/engine/mailbox-health.js.map +1 -0
  103. package/src/lib/engine/opt-out-intent.d.ts +41 -0
  104. package/src/lib/engine/opt-out-intent.js +220 -0
  105. package/src/lib/engine/opt-out-intent.js.map +1 -0
  106. package/src/lib/engine/recipient-country.d.ts +41 -0
  107. package/src/lib/engine/recipient-country.js +171 -0
  108. package/src/lib/engine/recipient-country.js.map +1 -0
  109. package/src/lib/engine/schedule.d.ts +70 -0
  110. package/src/lib/engine/schedule.js +115 -0
  111. package/src/lib/engine/schedule.js.map +1 -0
  112. package/src/lib/engine/sending-capacity.d.ts +96 -0
  113. package/src/lib/engine/sending-capacity.js +172 -0
  114. package/src/lib/engine/sending-capacity.js.map +1 -0
  115. package/src/lib/engine/sequence-validation.d.ts +90 -0
  116. package/src/lib/engine/sequence-validation.js +291 -0
  117. package/src/lib/engine/sequence-validation.js.map +1 -0
  118. package/src/lib/engine/thread-classification.d.ts +78 -0
  119. package/src/lib/engine/thread-classification.js +224 -0
  120. package/src/lib/engine/thread-classification.js.map +1 -0
  121. package/src/lib/engine/thread-message.d.ts +80 -0
  122. package/src/lib/engine/thread-message.js +143 -0
  123. package/src/lib/engine/thread-message.js.map +1 -0
  124. package/src/lib/enrollment/enroll-people.d.ts +81 -0
  125. package/src/lib/enrollment/enroll-people.js +250 -0
  126. package/src/lib/enrollment/enroll-people.js.map +1 -0
  127. package/src/lib/enrollment/gate-lookups.d.ts +32 -0
  128. package/src/lib/enrollment/gate-lookups.js +154 -0
  129. package/src/lib/enrollment/gate-lookups.js.map +1 -0
  130. package/src/lib/mailboxes/mailbox-api.d.ts +126 -0
  131. package/src/lib/mailboxes/mailbox-api.js +66 -0
  132. package/src/lib/mailboxes/mailbox-api.js.map +1 -0
  133. package/src/lib/mailboxes/mailbox-credentials.d.ts +95 -0
  134. package/src/lib/mailboxes/mailbox-credentials.js +102 -0
  135. package/src/lib/mailboxes/mailbox-credentials.js.map +1 -0
  136. package/src/lib/mailboxes/mailbox-erasure.d.ts +69 -0
  137. package/src/lib/mailboxes/mailbox-erasure.js +148 -0
  138. package/src/lib/mailboxes/mailbox-erasure.js.map +1 -0
  139. package/src/lib/mailboxes/mailbox-gate.d.ts +75 -0
  140. package/src/lib/mailboxes/mailbox-gate.js +98 -0
  141. package/src/lib/mailboxes/mailbox-gate.js.map +1 -0
  142. package/src/lib/mailboxes/mailbox-revoke.d.ts +59 -0
  143. package/src/lib/mailboxes/mailbox-revoke.js +41 -0
  144. package/src/lib/mailboxes/mailbox-revoke.js.map +1 -0
  145. package/src/lib/mailboxes/mailbox-routes.d.ts +119 -0
  146. package/src/lib/mailboxes/mailbox-routes.js +605 -0
  147. package/src/lib/mailboxes/mailbox-routes.js.map +1 -0
  148. package/src/lib/mailboxes/mailbox-settings.d.ts +110 -0
  149. package/src/lib/mailboxes/mailbox-settings.js +212 -0
  150. package/src/lib/mailboxes/mailbox-settings.js.map +1 -0
  151. package/src/lib/mailboxes/mailbox-transport.d.ts +64 -0
  152. package/src/lib/mailboxes/mailbox-transport.js +94 -0
  153. package/src/lib/mailboxes/mailbox-transport.js.map +1 -0
  154. package/src/lib/mailboxes/oauth-redirect.d.ts +41 -0
  155. package/src/lib/mailboxes/oauth-redirect.js +63 -0
  156. package/src/lib/mailboxes/oauth-redirect.js.map +1 -0
  157. package/src/lib/mailboxes/oauth-state.d.ts +152 -0
  158. package/src/lib/mailboxes/oauth-state.js +212 -0
  159. package/src/lib/mailboxes/oauth-state.js.map +1 -0
  160. package/src/lib/mailboxes/outreach-config.d.ts +64 -0
  161. package/src/lib/mailboxes/outreach-config.js +77 -0
  162. package/src/lib/mailboxes/outreach-config.js.map +1 -0
  163. package/src/lib/mailboxes/register-mailbox-routes.d.ts +47 -0
  164. package/src/lib/mailboxes/register-mailbox-routes.js +135 -0
  165. package/src/lib/mailboxes/register-mailbox-routes.js.map +1 -0
  166. package/src/lib/model/compliance-settings.d.ts +78 -0
  167. package/src/lib/model/compliance-settings.js +155 -0
  168. package/src/lib/model/compliance-settings.js.map +1 -0
  169. package/src/lib/model/outreach-api.d.ts +210 -0
  170. package/src/lib/model/outreach-api.js +28 -0
  171. package/src/lib/model/outreach-api.js.map +1 -0
  172. package/src/lib/model/outreach.types.d.ts +563 -0
  173. package/src/lib/model/outreach.types.js +225 -0
  174. package/src/lib/model/outreach.types.js.map +1 -0
  175. package/src/lib/model/sequence-draft.d.ts +84 -0
  176. package/src/lib/model/sequence-draft.js +239 -0
  177. package/src/lib/model/sequence-draft.js.map +1 -0
  178. package/src/lib/model/step-preview.d.ts +45 -0
  179. package/src/lib/model/step-preview.js +98 -0
  180. package/src/lib/model/step-preview.js.map +1 -0
  181. package/src/lib/model/stored-records.d.ts +23 -0
  182. package/src/lib/model/stored-records.js +84 -0
  183. package/src/lib/model/stored-records.js.map +1 -0
  184. package/src/lib/plugin.d.ts +46 -0
  185. package/src/lib/plugin.js +86 -0
  186. package/src/lib/plugin.js.map +1 -0
  187. package/src/lib/routes/enroll-routes.d.ts +64 -0
  188. package/src/lib/routes/enroll-routes.js +350 -0
  189. package/src/lib/routes/enroll-routes.js.map +1 -0
  190. package/src/lib/routes/enrollment-routes.d.ts +19 -0
  191. package/src/lib/routes/enrollment-routes.js +171 -0
  192. package/src/lib/routes/enrollment-routes.js.map +1 -0
  193. package/src/lib/routes/platform-deps.d.ts +51 -0
  194. package/src/lib/routes/platform-deps.js +66 -0
  195. package/src/lib/routes/platform-deps.js.map +1 -0
  196. package/src/lib/routes/preview-routes.d.ts +33 -0
  197. package/src/lib/routes/preview-routes.js +117 -0
  198. package/src/lib/routes/preview-routes.js.map +1 -0
  199. package/src/lib/routes/register-routes.d.ts +22 -0
  200. package/src/lib/routes/register-routes.js +92 -0
  201. package/src/lib/routes/register-routes.js.map +1 -0
  202. package/src/lib/routes/route-deps.d.ts +49 -0
  203. package/src/lib/routes/route-deps.js +27 -0
  204. package/src/lib/routes/route-deps.js.map +1 -0
  205. package/src/lib/routes/route-gate.d.ts +94 -0
  206. package/src/lib/routes/route-gate.js +87 -0
  207. package/src/lib/routes/route-gate.js.map +1 -0
  208. package/src/lib/routes/route-http.d.ts +32 -0
  209. package/src/lib/routes/route-http.js +62 -0
  210. package/src/lib/routes/route-http.js.map +1 -0
  211. package/src/lib/routes/sequence-routes.d.ts +32 -0
  212. package/src/lib/routes/sequence-routes.js +359 -0
  213. package/src/lib/routes/sequence-routes.js.map +1 -0
  214. package/src/lib/routes/settings-routes.d.ts +30 -0
  215. package/src/lib/routes/settings-routes.js +73 -0
  216. package/src/lib/routes/settings-routes.js.map +1 -0
  217. package/src/lib/runtime/enrollment-events.d.ts +86 -0
  218. package/src/lib/runtime/enrollment-events.js +141 -0
  219. package/src/lib/runtime/enrollment-events.js.map +1 -0
  220. package/src/lib/runtime/fixtures/fake-gmail.d.ts +121 -0
  221. package/src/lib/runtime/fixtures/fake-gmail.js +312 -0
  222. package/src/lib/runtime/fixtures/fake-gmail.js.map +1 -0
  223. package/src/lib/runtime/mailbox-health-store.d.ts +47 -0
  224. package/src/lib/runtime/mailbox-health-store.js +168 -0
  225. package/src/lib/runtime/mailbox-health-store.js.map +1 -0
  226. package/src/lib/runtime/person-erasure.d.ts +39 -0
  227. package/src/lib/runtime/person-erasure.js +57 -0
  228. package/src/lib/runtime/person-erasure.js.map +1 -0
  229. package/src/lib/runtime/platform-runtime-deps.d.ts +29 -0
  230. package/src/lib/runtime/platform-runtime-deps.js +98 -0
  231. package/src/lib/runtime/platform-runtime-deps.js.map +1 -0
  232. package/src/lib/runtime/runtime-deps.d.ts +77 -0
  233. package/src/lib/runtime/runtime-deps.js +18 -0
  234. package/src/lib/runtime/runtime-deps.js.map +1 -0
  235. package/src/lib/runtime/send-job.d.ts +42 -0
  236. package/src/lib/runtime/send-job.js +780 -0
  237. package/src/lib/runtime/send-job.js.map +1 -0
  238. package/src/lib/runtime/sync-job.d.ts +41 -0
  239. package/src/lib/runtime/sync-job.js +480 -0
  240. package/src/lib/runtime/sync-job.js.map +1 -0
  241. package/src/lib/runtime/timeline.d.ts +67 -0
  242. package/src/lib/runtime/timeline.js +93 -0
  243. package/src/lib/runtime/timeline.js.map +1 -0
  244. package/src/lib/runtime/unsubscribe-link.d.ts +75 -0
  245. package/src/lib/runtime/unsubscribe-link.js +121 -0
  246. package/src/lib/runtime/unsubscribe-link.js.map +1 -0
  247. package/src/lib/runtime/unsubscribe-route.d.ts +24 -0
  248. package/src/lib/runtime/unsubscribe-route.js +103 -0
  249. package/src/lib/runtime/unsubscribe-route.js.map +1 -0
  250. package/src/lib/server.d.ts +53 -0
  251. package/src/lib/server.js +94 -0
  252. package/src/lib/server.js.map +1 -0
  253. package/src/lib/storage/compliance-settings-store.d.ts +44 -0
  254. package/src/lib/storage/compliance-settings-store.js +78 -0
  255. package/src/lib/storage/compliance-settings-store.js.map +1 -0
  256. package/src/lib/storage/do-not-contact-store.d.ts +60 -0
  257. package/src/lib/storage/do-not-contact-store.js +168 -0
  258. package/src/lib/storage/do-not-contact-store.js.map +1 -0
  259. package/src/lib/storage/outreach-records.d.ts +33 -0
  260. package/src/lib/storage/outreach-records.js +35 -0
  261. package/src/lib/storage/outreach-records.js.map +1 -0
  262. package/src/lib/subprocessors.d.ts +48 -0
  263. package/src/lib/subprocessors.js +70 -0
  264. package/src/lib/subprocessors.js.map +1 -0
  265. package/src/lib/transport/gmail-client.d.ts +145 -0
  266. package/src/lib/transport/gmail-client.js +229 -0
  267. package/src/lib/transport/gmail-client.js.map +1 -0
  268. package/src/lib/transport/gmail-errors.d.ts +84 -0
  269. package/src/lib/transport/gmail-errors.js +138 -0
  270. package/src/lib/transport/gmail-errors.js.map +1 -0
  271. package/src/lib/transport/google-oauth.d.ts +138 -0
  272. package/src/lib/transport/google-oauth.js +247 -0
  273. package/src/lib/transport/google-oauth.js.map +1 -0
  274. package/src/lib/transport/http.d.ts +53 -0
  275. package/src/lib/transport/http.js +79 -0
  276. package/src/lib/transport/http.js.map +1 -0
  277. package/src/lib/transport/rfc5322.d.ts +116 -0
  278. package/src/lib/transport/rfc5322.js +330 -0
  279. package/src/lib/transport/rfc5322.js.map +1 -0
  280. package/src/lib/transport/send-message.d.ts +69 -0
  281. package/src/lib/transport/send-message.js +77 -0
  282. package/src/lib/transport/send-message.js.map +1 -0
@@ -0,0 +1,310 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Aglyn LLC
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */ 'use client';
17
+ import { _ as _extends } from "@swc/helpers/_/_extends";
18
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
19
+ import { pluginDocsHelp } from "@aglyn/aglyn";
20
+ import { mdiPlus } from "@aglyn/shared-data-mdi";
21
+ import { CardDisplay, MdiIcon } from "@aglyn/shared-ui-jsx";
22
+ import EmptyStateComponent from "@aglyn/shared-ui-jsx/components/empty-state.component";
23
+ import { ListPagination } from "@aglyn/shared-ui-jsx/components/list-pagination.component";
24
+ import { ListTable } from "@aglyn/shared-ui-jsx/components/list-table.component";
25
+ import { TABLE_PAGE_SIZE_DEFAULT } from "@aglyn/shared-ui-jsx/const/table-pagination";
26
+ import { Button, Card, CardContent, Chip, Stack, Typography, useMediaQuery, useTheme } from "@mui/material";
27
+ import { useState } from "react";
28
+ import { OutreachLink, OutreachLoading, OutreachLoadProblem, OutreachSequenceStatusChip, useOutreachNavigate } from "./outreach-ui.js";
29
+ import { OutreachSequenceDetail } from "./sequence-detail.js";
30
+ import { OutreachSequenceEditor } from "./sequence-editor.js";
31
+ import { useOutreachApi } from "./use-outreach-api.js";
32
+ import { useOutreachSequenceCounts, useOutreachSequences } from "./use-outreach-data.js";
33
+ import { useOutreachMailboxes } from "./use-outreach-mailboxes.js";
34
+ import { useOutreachComplianceSettings } from "./use-outreach-settings.js";
35
+ /** The new-sequence page's segment below the section. */ export const OUTREACH_NEW_SEQUENCE_SEGMENT = 'new';
36
+ /**
37
+ * The Sequences section (AGL-2980), and the pages below it: the list, a new
38
+ * sequence, and one sequence's steps and enrollments. Each is a real URL, so
39
+ * a sequence is a link a rep can keep and the back button walks them.
40
+ */ export function OutreachSequencesSection(props) {
41
+ const { orgId, sectionPath, subpath } = props;
42
+ const api = useOutreachApi(orgId);
43
+ const settings = useOutreachComplianceSettings(api, orgId);
44
+ const mailboxes = useOutreachMailboxes(orgId);
45
+ const navigate = useOutreachNavigate();
46
+ if (!orgId) return /*#__PURE__*/ _jsx(OutreachLoading, {
47
+ label: "Loading sequences…"
48
+ });
49
+ const [first, second] = subpath;
50
+ if (first === OUTREACH_NEW_SEQUENCE_SEGMENT) {
51
+ return /*#__PURE__*/ _jsxs(Stack, {
52
+ spacing: 2,
53
+ children: [
54
+ /*#__PURE__*/ _jsx(OutreachLink, {
55
+ href: sectionPath,
56
+ children: "Sequences"
57
+ }),
58
+ /*#__PURE__*/ _jsx(Typography, {
59
+ variant: "h5",
60
+ component: "h2",
61
+ children: "New sequence"
62
+ }),
63
+ /*#__PURE__*/ _jsx(OutreachSequenceEditor, {
64
+ orgId: orgId,
65
+ orgMount: props.orgMount,
66
+ sequence: null,
67
+ settings: settings,
68
+ mailboxes: mailboxes,
69
+ mailboxesPath: props.mailboxesPath,
70
+ onSaved: (sequence)=>navigate(`${sectionPath}/${sequence.id}`),
71
+ onCancel: ()=>navigate(sectionPath)
72
+ })
73
+ ]
74
+ });
75
+ }
76
+ if (first) {
77
+ return /*#__PURE__*/ _jsx(OutreachSequenceDetail, {
78
+ orgId: orgId,
79
+ orgMount: props.orgMount,
80
+ org: props.org,
81
+ sectionPath: sectionPath,
82
+ sequenceId: first,
83
+ tab: second === 'enrollments' ? 'enrollments' : 'steps',
84
+ settings: settings,
85
+ mailboxes: mailboxes,
86
+ mailboxesPath: props.mailboxesPath,
87
+ compliancePath: props.compliancePath
88
+ });
89
+ }
90
+ return /*#__PURE__*/ _jsx(OutreachSequenceList, {
91
+ orgId: orgId,
92
+ sectionPath: sectionPath,
93
+ mailboxes: mailboxes.mailboxes
94
+ });
95
+ }
96
+ OutreachSequencesSection.displayName = 'OutreachSequencesSection';
97
+ const COUNT_COLUMNS = [
98
+ [
99
+ 'enrolled',
100
+ 'Enrolled'
101
+ ],
102
+ [
103
+ 'active',
104
+ 'Active'
105
+ ],
106
+ [
107
+ 'replied',
108
+ 'Replied'
109
+ ],
110
+ [
111
+ 'bounced',
112
+ 'Bounced'
113
+ ],
114
+ [
115
+ 'optedOut',
116
+ 'Opted out'
117
+ ]
118
+ ];
119
+ /**
120
+ * Every sequence: its mailbox, its status, and how many people it enrolled
121
+ * and where they stand — a table on wider screens, cards on a phone.
122
+ */ export function OutreachSequenceList(props) {
123
+ const { orgId, sectionPath } = props;
124
+ const theme = useTheme();
125
+ const narrow = useMediaQuery(theme.breakpoints.down('md'));
126
+ const navigate = useOutreachNavigate();
127
+ const sequences = useOutreachSequences(orgId);
128
+ const [page, setPage] = useState(0);
129
+ const [pageSize, setPageSize] = useState(TABLE_PAGE_SIZE_DEFAULT);
130
+ const pageRows = sequences.data.slice(page * pageSize, (page + 1) * pageSize);
131
+ // Counted for the page on screen only: five aggregations a sequence.
132
+ const counts = useOutreachSequenceCounts(orgId, pageRows.map((sequence)=>sequence.id));
133
+ const footer = /*#__PURE__*/ _jsx(ListPagination, {
134
+ page: page,
135
+ pageSize: pageSize,
136
+ rowCount: pageRows.length,
137
+ count: sequences.data.length,
138
+ onPageChange: setPage,
139
+ onPageSizeChange: setPageSize
140
+ });
141
+ const newHref = `${sectionPath}/${OUTREACH_NEW_SEQUENCE_SEGMENT}`;
142
+ const newButton = /*#__PURE__*/ _jsx(Button, {
143
+ variant: "contained",
144
+ startIcon: /*#__PURE__*/ _jsx(MdiIcon, {
145
+ path: mdiPlus.path,
146
+ fontSize: "small"
147
+ }),
148
+ href: newHref,
149
+ onClick: (event)=>{
150
+ event.preventDefault();
151
+ navigate(newHref);
152
+ },
153
+ children: "New sequence"
154
+ });
155
+ const mailboxLabel = (sequence)=>{
156
+ const mailbox = props.mailboxes.find((entry)=>entry.id === sequence.mailboxId);
157
+ return mailbox ? mailbox.sendAs || mailbox.email : sequence.mailboxId ? 'Mailbox removed' : 'No mailbox yet';
158
+ };
159
+ const count = (sequence, key)=>counts[sequence.id] ? String(counts[sequence.id][key]) : '—';
160
+ let body;
161
+ if (sequences.status === 'loading') body = /*#__PURE__*/ _jsx(OutreachLoading, {
162
+ label: "Loading sequences…"
163
+ });
164
+ else if (sequences.status === 'error' || sequences.status === 'refused') {
165
+ body = /*#__PURE__*/ _jsx(OutreachLoadProblem, {
166
+ status: sequences.status,
167
+ what: "sequences"
168
+ });
169
+ } else if (!sequences.data.length) {
170
+ body = /*#__PURE__*/ _jsx(Card, {
171
+ variant: "outlined",
172
+ children: /*#__PURE__*/ _jsx(EmptyStateComponent, {
173
+ label: "No sequences yet",
174
+ description: "A sequence is the emails, and the tasks between them, one person gets from one rep.",
175
+ action: newButton
176
+ })
177
+ });
178
+ } else if (narrow) {
179
+ body = /*#__PURE__*/ _jsxs(Stack, {
180
+ spacing: 1,
181
+ children: [
182
+ /*#__PURE__*/ _jsx(Stack, {
183
+ spacing: 1,
184
+ component: "ul",
185
+ sx: {
186
+ listStyle: 'none',
187
+ p: 0,
188
+ m: 0
189
+ },
190
+ "aria-label": "Sequences",
191
+ children: pageRows.map((sequence)=>/*#__PURE__*/ _jsx(Card, {
192
+ variant: "outlined",
193
+ component: "li",
194
+ children: /*#__PURE__*/ _jsx(CardContent, {
195
+ children: /*#__PURE__*/ _jsxs(Stack, {
196
+ spacing: 1,
197
+ children: [
198
+ /*#__PURE__*/ _jsxs(Stack, {
199
+ direction: "row",
200
+ spacing: 1,
201
+ sx: {
202
+ alignItems: 'center',
203
+ justifyContent: 'space-between'
204
+ },
205
+ children: [
206
+ /*#__PURE__*/ _jsx(OutreachLink, {
207
+ href: `${sectionPath}/${sequence.id}`,
208
+ children: sequence.name || 'Untitled'
209
+ }),
210
+ /*#__PURE__*/ _jsx(OutreachSequenceStatusChip, {
211
+ status: sequence.status
212
+ })
213
+ ]
214
+ }),
215
+ /*#__PURE__*/ _jsx(Typography, {
216
+ variant: "body2",
217
+ color: "text.secondary",
218
+ children: mailboxLabel(sequence)
219
+ }),
220
+ /*#__PURE__*/ _jsx(Stack, {
221
+ direction: "row",
222
+ spacing: 0.5,
223
+ sx: {
224
+ flexWrap: 'wrap',
225
+ rowGap: 0.5
226
+ },
227
+ children: COUNT_COLUMNS.map(([key, label])=>/*#__PURE__*/ _jsx(Chip, {
228
+ size: "small",
229
+ variant: "outlined",
230
+ label: `${label} ${count(sequence, key)}`
231
+ }, key))
232
+ })
233
+ ]
234
+ })
235
+ })
236
+ }, sequence.id))
237
+ }),
238
+ footer
239
+ ]
240
+ });
241
+ } else {
242
+ const columns = [
243
+ {
244
+ field: 'name',
245
+ headerName: 'Name',
246
+ flex: 1,
247
+ minWidth: 180
248
+ },
249
+ {
250
+ field: 'mailbox',
251
+ headerName: 'Mailbox',
252
+ flex: 1,
253
+ minWidth: 180
254
+ },
255
+ {
256
+ field: 'status',
257
+ headerName: 'Status',
258
+ width: 110,
259
+ renderCell: ({ row })=>/*#__PURE__*/ _jsx(OutreachSequenceStatusChip, {
260
+ status: row.status
261
+ })
262
+ },
263
+ ...COUNT_COLUMNS.map(([key, label])=>({
264
+ field: key,
265
+ headerName: label,
266
+ width: 96,
267
+ align: 'right',
268
+ headerAlign: 'right'
269
+ }))
270
+ ];
271
+ body = /*#__PURE__*/ _jsxs(Stack, {
272
+ spacing: 1,
273
+ children: [
274
+ /*#__PURE__*/ _jsx(ListTable, {
275
+ "aria-label": "Sequences",
276
+ columns: columns,
277
+ rows: pageRows.map((sequence)=>_extends({
278
+ $id: sequence.id,
279
+ name: sequence.name || 'Untitled',
280
+ mailbox: mailboxLabel(sequence),
281
+ status: sequence.status
282
+ }, Object.fromEntries(COUNT_COLUMNS.map(([key])=>[
283
+ key,
284
+ count(sequence, key)
285
+ ])))),
286
+ onOpen: (id)=>navigate(`${sectionPath}/${id}`),
287
+ quickFilter: false,
288
+ hideFooter: true
289
+ }),
290
+ footer
291
+ ]
292
+ });
293
+ }
294
+ return /*#__PURE__*/ _jsx(CardDisplay, {
295
+ header: "Sequences",
296
+ help: pluginDocsHelp('sequences', {
297
+ anchor: '#sequences'
298
+ }),
299
+ HeaderProps: {
300
+ action: sequences.status === 'ready' && sequences.data.length ? newButton : undefined
301
+ },
302
+ contentGutterX: true,
303
+ contentGutterY: true,
304
+ children: body
305
+ });
306
+ }
307
+ OutreachSequenceList.displayName = 'OutreachSequenceList';
308
+ export default OutreachSequencesSection;
309
+
310
+ //# sourceMappingURL=sequences-section.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../../../libs/plugins/outreach/src/lib/components/sequences-section.tsx"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n'use client'\n\nimport { pluginDocsHelp, type ConsolePluginOrgMount } from '@aglyn/aglyn'\nimport { mdiPlus } from '@aglyn/shared-data-mdi'\nimport { CardDisplay, MdiIcon } from '@aglyn/shared-ui-jsx'\nimport EmptyStateComponent from '@aglyn/shared-ui-jsx/components/empty-state.component'\nimport { ListPagination } from '@aglyn/shared-ui-jsx/components/list-pagination.component'\nimport {\n ListTable,\n type ListTableProps,\n} from '@aglyn/shared-ui-jsx/components/list-table.component'\nimport { TABLE_PAGE_SIZE_DEFAULT } from '@aglyn/shared-ui-jsx/const/table-pagination'\nimport {\n Button,\n Card,\n CardContent,\n Chip,\n Stack,\n Typography,\n useMediaQuery,\n useTheme,\n} from '@mui/material'\nimport { useState } from 'react'\nimport type { OutreachMailbox, OutreachSequence } from '../model/outreach.types'\nimport {\n OutreachLink,\n OutreachLoading,\n OutreachLoadProblem,\n OutreachSequenceStatusChip,\n useOutreachNavigate,\n} from './outreach-ui'\nimport {\n OutreachSequenceDetail,\n type OutreachSequenceTab,\n} from './sequence-detail'\nimport { OutreachSequenceEditor } from './sequence-editor'\nimport { useOutreachApi } from './use-outreach-api'\nimport {\n type OutreachSequenceCounts,\n useOutreachSequenceCounts,\n useOutreachSequences,\n} from './use-outreach-data'\nimport { useOutreachMailboxes } from './use-outreach-mailboxes'\nimport { useOutreachComplianceSettings } from './use-outreach-settings'\n\nexport interface OutreachSequencesSectionProps {\n /** The organization the hub is mounted under; `null` until the shell knows it. */\n orgId: string | null\n orgMount?: ConsolePluginOrgMount\n org?: Record<string, unknown> | null\n /** The section's own path: `/[orgSlug]/outreach/sequences`. */\n sectionPath: string\n /** The path below the section: `[]`, `['new']`, `[id]` or `[id, 'enrollments']`. */\n subpath: readonly string[]\n /** The Mailboxes section: `/[orgSlug]/outreach/mailboxes`. */\n mailboxesPath: string\n /** The Compliance section: `/[orgSlug]/outreach/compliance`. */\n compliancePath: string\n}\n\n/** The new-sequence page's segment below the section. */\nexport const OUTREACH_NEW_SEQUENCE_SEGMENT = 'new'\n\n/**\n * The Sequences section (AGL-2980), and the pages below it: the list, a new\n * sequence, and one sequence's steps and enrollments. Each is a real URL, so\n * a sequence is a link a rep can keep and the back button walks them.\n */\nexport function OutreachSequencesSection(props: OutreachSequencesSectionProps) {\n const { orgId, sectionPath, subpath } = props\n const api = useOutreachApi(orgId)\n const settings = useOutreachComplianceSettings(api, orgId)\n const mailboxes = useOutreachMailboxes(orgId)\n const navigate = useOutreachNavigate()\n\n if (!orgId) return <OutreachLoading label=\"Loading sequences…\" />\n const [first, second] = subpath\n if (first === OUTREACH_NEW_SEQUENCE_SEGMENT) {\n return (\n <Stack spacing={2}>\n <OutreachLink href={sectionPath}>Sequences</OutreachLink>\n <Typography variant=\"h5\" component=\"h2\">\n New sequence\n </Typography>\n <OutreachSequenceEditor\n orgId={orgId}\n orgMount={props.orgMount}\n sequence={null}\n settings={settings}\n mailboxes={mailboxes}\n mailboxesPath={props.mailboxesPath}\n onSaved={(sequence) => navigate(`${sectionPath}/${sequence.id}`)}\n onCancel={() => navigate(sectionPath)}\n />\n </Stack>\n )\n }\n if (first) {\n return (\n <OutreachSequenceDetail\n orgId={orgId}\n orgMount={props.orgMount}\n org={props.org}\n sectionPath={sectionPath}\n sequenceId={first}\n tab={\n (second === 'enrollments'\n ? 'enrollments'\n : 'steps') as OutreachSequenceTab\n }\n settings={settings}\n mailboxes={mailboxes}\n mailboxesPath={props.mailboxesPath}\n compliancePath={props.compliancePath}\n />\n )\n }\n return (\n <OutreachSequenceList\n orgId={orgId}\n sectionPath={sectionPath}\n mailboxes={mailboxes.mailboxes}\n />\n )\n}\nOutreachSequencesSection.displayName = 'OutreachSequencesSection'\n\nconst COUNT_COLUMNS: ReadonlyArray<[keyof OutreachSequenceCounts, string]> = [\n ['enrolled', 'Enrolled'],\n ['active', 'Active'],\n ['replied', 'Replied'],\n ['bounced', 'Bounced'],\n ['optedOut', 'Opted out'],\n]\n\n/**\n * Every sequence: its mailbox, its status, and how many people it enrolled\n * and where they stand — a table on wider screens, cards on a phone.\n */\nexport function OutreachSequenceList(props: {\n orgId: string\n sectionPath: string\n mailboxes: readonly OutreachMailbox[]\n}) {\n const { orgId, sectionPath } = props\n const theme = useTheme()\n const narrow = useMediaQuery(theme.breakpoints.down('md'))\n const navigate = useOutreachNavigate()\n const sequences = useOutreachSequences(orgId)\n const [page, setPage] = useState(0)\n const [pageSize, setPageSize] = useState(TABLE_PAGE_SIZE_DEFAULT)\n const pageRows = sequences.data.slice(page * pageSize, (page + 1) * pageSize)\n // Counted for the page on screen only: five aggregations a sequence.\n const counts = useOutreachSequenceCounts(\n orgId,\n pageRows.map((sequence) => sequence.id),\n )\n const footer = (\n <ListPagination\n page={page}\n pageSize={pageSize}\n rowCount={pageRows.length}\n count={sequences.data.length}\n onPageChange={setPage}\n onPageSizeChange={setPageSize}\n />\n )\n const newHref = `${sectionPath}/${OUTREACH_NEW_SEQUENCE_SEGMENT}`\n const newButton = (\n <Button\n variant=\"contained\"\n startIcon={<MdiIcon path={mdiPlus.path} fontSize=\"small\" />}\n href={newHref}\n onClick={(event) => {\n event.preventDefault()\n navigate(newHref)\n }}\n >\n New sequence\n </Button>\n )\n const mailboxLabel = (sequence: OutreachSequence) => {\n const mailbox = props.mailboxes.find(\n (entry) => entry.id === sequence.mailboxId,\n )\n return mailbox\n ? mailbox.sendAs || mailbox.email\n : sequence.mailboxId\n ? 'Mailbox removed'\n : 'No mailbox yet'\n }\n const count = (\n sequence: OutreachSequence,\n key: keyof OutreachSequenceCounts,\n ) => (counts[sequence.id] ? String(counts[sequence.id][key]) : '—')\n\n let body\n if (sequences.status === 'loading')\n body = <OutreachLoading label=\"Loading sequences…\" />\n else if (sequences.status === 'error' || sequences.status === 'refused') {\n body = <OutreachLoadProblem status={sequences.status} what=\"sequences\" />\n } else if (!sequences.data.length) {\n body = (\n <Card variant=\"outlined\">\n <EmptyStateComponent\n label=\"No sequences yet\"\n description=\"A sequence is the emails, and the tasks between them, one person gets from one rep.\"\n action={newButton}\n />\n </Card>\n )\n } else if (narrow) {\n body = (\n <Stack spacing={1}>\n <Stack\n spacing={1}\n component=\"ul\"\n sx={{ listStyle: 'none', p: 0, m: 0 }}\n aria-label=\"Sequences\"\n >\n {pageRows.map((sequence) => (\n <Card key={sequence.id} variant=\"outlined\" component=\"li\">\n <CardContent>\n <Stack spacing={1}>\n <Stack\n direction=\"row\"\n spacing={1}\n sx={{\n alignItems: 'center',\n justifyContent: 'space-between',\n }}\n >\n <OutreachLink href={`${sectionPath}/${sequence.id}`}>\n {sequence.name || 'Untitled'}\n </OutreachLink>\n <OutreachSequenceStatusChip status={sequence.status} />\n </Stack>\n <Typography variant=\"body2\" color=\"text.secondary\">\n {mailboxLabel(sequence)}\n </Typography>\n <Stack\n direction=\"row\"\n spacing={0.5}\n sx={{ flexWrap: 'wrap', rowGap: 0.5 }}\n >\n {COUNT_COLUMNS.map(([key, label]) => (\n <Chip\n key={key}\n size=\"small\"\n variant=\"outlined\"\n label={`${label} ${count(sequence, key)}`}\n />\n ))}\n </Stack>\n </Stack>\n </CardContent>\n </Card>\n ))}\n </Stack>\n {footer}\n </Stack>\n )\n } else {\n const columns: NonNullable<ListTableProps['columns']> = [\n { field: 'name', headerName: 'Name', flex: 1, minWidth: 180 },\n { field: 'mailbox', headerName: 'Mailbox', flex: 1, minWidth: 180 },\n {\n field: 'status',\n headerName: 'Status',\n width: 110,\n renderCell: ({ row }) => (\n <OutreachSequenceStatusChip status={row.status} />\n ),\n },\n ...COUNT_COLUMNS.map(([key, label]) => ({\n field: key,\n headerName: label,\n width: 96,\n align: 'right' as const,\n headerAlign: 'right' as const,\n })),\n ]\n body = (\n <Stack spacing={1}>\n <ListTable\n aria-label=\"Sequences\"\n columns={columns}\n rows={pageRows.map((sequence) => ({\n $id: sequence.id,\n name: sequence.name || 'Untitled',\n mailbox: mailboxLabel(sequence),\n status: sequence.status,\n ...Object.fromEntries(\n COUNT_COLUMNS.map(([key]) => [key, count(sequence, key)]),\n ),\n }))}\n onOpen={(id) => navigate(`${sectionPath}/${id}`)}\n quickFilter={false}\n hideFooter\n />\n {footer}\n </Stack>\n )\n }\n\n return (\n <CardDisplay\n header=\"Sequences\"\n help={pluginDocsHelp('sequences', { anchor: '#sequences' })}\n HeaderProps={{\n action:\n sequences.status === 'ready' && sequences.data.length\n ? newButton\n : undefined,\n }}\n contentGutterX\n contentGutterY\n >\n {body}\n </CardDisplay>\n )\n}\nOutreachSequenceList.displayName = 'OutreachSequenceList'\n\nexport default OutreachSequencesSection\n"],"names":["pluginDocsHelp","mdiPlus","CardDisplay","MdiIcon","EmptyStateComponent","ListPagination","ListTable","TABLE_PAGE_SIZE_DEFAULT","Button","Card","CardContent","Chip","Stack","Typography","useMediaQuery","useTheme","useState","OutreachLink","OutreachLoading","OutreachLoadProblem","OutreachSequenceStatusChip","useOutreachNavigate","OutreachSequenceDetail","OutreachSequenceEditor","useOutreachApi","useOutreachSequenceCounts","useOutreachSequences","useOutreachMailboxes","useOutreachComplianceSettings","OUTREACH_NEW_SEQUENCE_SEGMENT","OutreachSequencesSection","props","orgId","sectionPath","subpath","api","settings","mailboxes","navigate","label","first","second","spacing","href","variant","component","orgMount","sequence","mailboxesPath","onSaved","id","onCancel","org","sequenceId","tab","compliancePath","OutreachSequenceList","displayName","COUNT_COLUMNS","theme","narrow","breakpoints","down","sequences","page","setPage","pageSize","setPageSize","pageRows","data","slice","counts","map","footer","rowCount","length","count","onPageChange","onPageSizeChange","newHref","newButton","startIcon","path","fontSize","onClick","event","preventDefault","mailboxLabel","mailbox","find","entry","mailboxId","sendAs","email","key","String","body","status","what","description","action","sx","listStyle","p","m","aria-label","direction","alignItems","justifyContent","name","color","flexWrap","rowGap","size","columns","field","headerName","flex","minWidth","width","renderCell","row","align","headerAlign","rows","$id","Object","fromEntries","onOpen","quickFilter","hideFooter","header","help","anchor","HeaderProps","undefined","contentGutterX","contentGutterY"],"mappings":"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"}
@@ -0,0 +1,38 @@
1
+ import type { OutreachComplianceIssue } from '../model/compliance-settings';
2
+ import type { OutreachEnrollmentAction, OutreachEnrollmentActionResponse, OutreachEnrollPersonRequest, OutreachEnrollPreviewResponse, OutreachEnrollResponse, OutreachEnrollSource, OutreachPreviewRequest, OutreachPreviewResponse, OutreachRouteRefusalReason, OutreachSequenceAction, OutreachSequenceSaveResponse, OutreachSequenceStatusResponse, OutreachSettingsResponse, OutreachSettingsSaveRequest, OutreachSettingsSaveResponse } from '../model/outreach-api';
3
+ import type { OutreachSequenceDraft, OutreachSequenceIssue } from '../model/sequence-draft';
4
+ /**
5
+ * A route's refusal, carrying its sentence, its stable reason and any
6
+ * field-level issues. `refused` is the one a page shows as "you can't use
7
+ * this here" rather than as something that went wrong: no permission, no
8
+ * entitlement, or the release gate answering as if the route did not exist.
9
+ */
10
+ export declare class OutreachRouteError extends Error {
11
+ readonly reason: OutreachRouteRefusalReason | 'unreachable' | 'not-found';
12
+ readonly status: number;
13
+ readonly issues: ReadonlyArray<OutreachComplianceIssue | OutreachSequenceIssue>;
14
+ constructor(message: string, reason: OutreachRouteError['reason'], status: number, issues?: OutreachRouteError['issues']);
15
+ get refused(): boolean;
16
+ }
17
+ /** The routes, as the Outreach pages call them. */
18
+ export interface OutreachApi {
19
+ readSettings(): Promise<OutreachSettingsResponse>;
20
+ saveSettings(input: Omit<OutreachSettingsSaveRequest, 'orgId'>): Promise<OutreachSettingsSaveResponse>;
21
+ saveSequence(sequenceId: string | null, sequence: OutreachSequenceDraft): Promise<OutreachSequenceSaveResponse>;
22
+ setSequenceStatus(sequenceId: string, action: OutreachSequenceAction): Promise<OutreachSequenceStatusResponse>;
23
+ deleteSequence(sequenceId: string): Promise<{
24
+ ok: true;
25
+ }>;
26
+ previewEnrollment(sequenceId: string, source: OutreachEnrollSource): Promise<OutreachEnrollPreviewResponse>;
27
+ enroll(sequenceId: string, people: OutreachEnrollPersonRequest[]): Promise<OutreachEnrollResponse>;
28
+ actOnEnrollment(enrollmentId: string, action: OutreachEnrollmentAction, detail?: string): Promise<OutreachEnrollmentActionResponse>;
29
+ previewEmail(input: Omit<OutreachPreviewRequest, 'orgId'>): Promise<OutreachPreviewResponse>;
30
+ }
31
+ /**
32
+ * The Outreach pages' one door to the settings, sequence and enrollment
33
+ * routes (AGL-2980), with the member's session attached and the
34
+ * organization named on every call. A refusal is thrown as an
35
+ * {@link OutreachRouteError} carrying the route's own sentence, which is
36
+ * written for the person reading it.
37
+ */
38
+ export declare function useOutreachApi(orgId: string | null): OutreachApi;
@@ -0,0 +1,139 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Aglyn LLC
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */ 'use client';
17
+ import { _ as _extends } from "@swc/helpers/_/_extends";
18
+ import { authorizedFetch } from "@aglyn/shared-util-http/authorized-token";
19
+ import { useUser } from "@aglyn/tenant-feature-instance";
20
+ import { useCallback, useMemo } from "react";
21
+ import { OUTREACH_API_ROUTES } from "../constants/api-routes.js";
22
+ /**
23
+ * A route's refusal, carrying its sentence, its stable reason and any
24
+ * field-level issues. `refused` is the one a page shows as "you can't use
25
+ * this here" rather than as something that went wrong: no permission, no
26
+ * entitlement, or the release gate answering as if the route did not exist.
27
+ */ export class OutreachRouteError extends Error {
28
+ get refused() {
29
+ return this.reason === 'permission' || this.reason === 'entitlement' || this.reason === 'not-org-wide' || this.reason === 'not-a-member' || // The dispatcher answers a route whose plugin is not released to this
30
+ // workspace as though it did not exist.
31
+ this.reason === 'not-found';
32
+ }
33
+ constructor(message, reason, status, issues = []){
34
+ super(message);
35
+ this.name = 'OutreachRouteError';
36
+ this.reason = reason;
37
+ this.status = status;
38
+ this.issues = issues;
39
+ }
40
+ }
41
+ /**
42
+ * The Outreach pages' one door to the settings, sequence and enrollment
43
+ * routes (AGL-2980), with the member's session attached and the
44
+ * organization named on every call. A refusal is thrown as an
45
+ * {@link OutreachRouteError} carrying the route's own sentence, which is
46
+ * written for the person reading it.
47
+ */ export function useOutreachApi(orgId) {
48
+ const { data: user } = useUser();
49
+ const call = useCallback(async (route, init)=>{
50
+ if (!orgId) throw new OutreachRouteError('Open an organization first.', 'org-required', 400);
51
+ const path = init.method === 'GET' ? `/api/${route}?orgId=${encodeURIComponent(orgId)}` : `/api/${route}`;
52
+ let response;
53
+ try {
54
+ response = await authorizedFetch(user, path, _extends({
55
+ method: init.method
56
+ }, init.method === 'POST' ? {
57
+ headers: {
58
+ 'Content-Type': 'application/json'
59
+ },
60
+ body: JSON.stringify(_extends({
61
+ orgId
62
+ }, init.body))
63
+ } : {}));
64
+ } catch (unused) {
65
+ throw new OutreachRouteError('Sequences could not be reached. Try again.', 'unreachable', 0);
66
+ }
67
+ const payload = await response.json().catch(()=>null);
68
+ if (!response.ok || !payload) {
69
+ var _refusal_reason, _refusal_issues;
70
+ const refusal = payload != null ? payload : {};
71
+ throw new OutreachRouteError(refusal.error && refusal.reason ? refusal.error : response.status === 404 ? "Sequences isn't available to this workspace yet." : 'Sequences could not be reached. Try again.', (_refusal_reason = refusal.reason) != null ? _refusal_reason : response.status === 404 ? 'not-found' : 'unreachable', response.status, (_refusal_issues = refusal.issues) != null ? _refusal_issues : []);
72
+ }
73
+ return payload;
74
+ }, [
75
+ user,
76
+ orgId
77
+ ]);
78
+ return useMemo(()=>({
79
+ readSettings: ()=>call(OUTREACH_API_ROUTES.settings, {
80
+ method: 'GET'
81
+ }),
82
+ saveSettings: (input)=>call(OUTREACH_API_ROUTES.settings, {
83
+ method: 'POST',
84
+ body: _extends({}, input)
85
+ }),
86
+ saveSequence: (sequenceId, sequence)=>call(OUTREACH_API_ROUTES.sequencesSave, {
87
+ method: 'POST',
88
+ body: _extends({}, sequenceId ? {
89
+ sequenceId
90
+ } : {}, {
91
+ sequence
92
+ })
93
+ }),
94
+ setSequenceStatus: (sequenceId, action)=>call(OUTREACH_API_ROUTES.sequencesStatus, {
95
+ method: 'POST',
96
+ body: {
97
+ sequenceId,
98
+ action
99
+ }
100
+ }),
101
+ deleteSequence: (sequenceId)=>call(OUTREACH_API_ROUTES.sequencesDelete, {
102
+ method: 'POST',
103
+ body: {
104
+ sequenceId
105
+ }
106
+ }),
107
+ previewEnrollment: (sequenceId, source)=>call(OUTREACH_API_ROUTES.enrollPreview, {
108
+ method: 'POST',
109
+ body: {
110
+ sequenceId,
111
+ source
112
+ }
113
+ }),
114
+ enroll: (sequenceId, people)=>call(OUTREACH_API_ROUTES.enroll, {
115
+ method: 'POST',
116
+ body: {
117
+ sequenceId,
118
+ people
119
+ }
120
+ }),
121
+ actOnEnrollment: (enrollmentId, action, detail)=>call(OUTREACH_API_ROUTES.enrollmentsAction, {
122
+ method: 'POST',
123
+ body: _extends({
124
+ enrollmentId,
125
+ action
126
+ }, detail ? {
127
+ detail
128
+ } : {})
129
+ }),
130
+ previewEmail: (input)=>call(OUTREACH_API_ROUTES.preview, {
131
+ method: 'POST',
132
+ body: _extends({}, input)
133
+ })
134
+ }), [
135
+ call
136
+ ]);
137
+ }
138
+
139
+ //# sourceMappingURL=use-outreach-api.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../../../libs/plugins/outreach/src/lib/components/use-outreach-api.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n'use client'\n\nimport { authorizedFetch } from '@aglyn/shared-util-http/authorized-token'\nimport { useUser } from '@aglyn/tenant-feature-instance'\nimport { useCallback, useMemo } from 'react'\nimport { OUTREACH_API_ROUTES } from '../constants/api-routes'\nimport type { OutreachComplianceIssue } from '../model/compliance-settings'\nimport type {\n OutreachEnrollmentAction,\n OutreachEnrollmentActionResponse,\n OutreachEnrollPersonRequest,\n OutreachEnrollPreviewResponse,\n OutreachEnrollResponse,\n OutreachEnrollSource,\n OutreachPreviewRequest,\n OutreachPreviewResponse,\n OutreachRouteRefusal,\n OutreachRouteRefusalReason,\n OutreachSequenceAction,\n OutreachSequenceSaveResponse,\n OutreachSequenceStatusResponse,\n OutreachSettingsResponse,\n OutreachSettingsSaveRequest,\n OutreachSettingsSaveResponse,\n} from '../model/outreach-api'\nimport type {\n OutreachSequenceDraft,\n OutreachSequenceIssue,\n} from '../model/sequence-draft'\n\n/**\n * A route's refusal, carrying its sentence, its stable reason and any\n * field-level issues. `refused` is the one a page shows as \"you can't use\n * this here\" rather than as something that went wrong: no permission, no\n * entitlement, or the release gate answering as if the route did not exist.\n */\nexport class OutreachRouteError extends Error {\n readonly reason: OutreachRouteRefusalReason | 'unreachable' | 'not-found'\n readonly status: number\n readonly issues: ReadonlyArray<\n OutreachComplianceIssue | OutreachSequenceIssue\n >\n\n constructor(\n message: string,\n reason: OutreachRouteError['reason'],\n status: number,\n issues: OutreachRouteError['issues'] = [],\n ) {\n super(message)\n this.name = 'OutreachRouteError'\n this.reason = reason\n this.status = status\n this.issues = issues\n }\n\n get refused(): boolean {\n return (\n this.reason === 'permission' ||\n this.reason === 'entitlement' ||\n this.reason === 'not-org-wide' ||\n this.reason === 'not-a-member' ||\n // The dispatcher answers a route whose plugin is not released to this\n // workspace as though it did not exist.\n this.reason === 'not-found'\n )\n }\n}\n\n/** The routes, as the Outreach pages call them. */\nexport interface OutreachApi {\n readSettings(): Promise<OutreachSettingsResponse>\n saveSettings(\n input: Omit<OutreachSettingsSaveRequest, 'orgId'>,\n ): Promise<OutreachSettingsSaveResponse>\n saveSequence(\n sequenceId: string | null,\n sequence: OutreachSequenceDraft,\n ): Promise<OutreachSequenceSaveResponse>\n setSequenceStatus(\n sequenceId: string,\n action: OutreachSequenceAction,\n ): Promise<OutreachSequenceStatusResponse>\n deleteSequence(sequenceId: string): Promise<{ ok: true }>\n previewEnrollment(\n sequenceId: string,\n source: OutreachEnrollSource,\n ): Promise<OutreachEnrollPreviewResponse>\n enroll(\n sequenceId: string,\n people: OutreachEnrollPersonRequest[],\n ): Promise<OutreachEnrollResponse>\n actOnEnrollment(\n enrollmentId: string,\n action: OutreachEnrollmentAction,\n detail?: string,\n ): Promise<OutreachEnrollmentActionResponse>\n previewEmail(\n input: Omit<OutreachPreviewRequest, 'orgId'>,\n ): Promise<OutreachPreviewResponse>\n}\n\n/**\n * The Outreach pages' one door to the settings, sequence and enrollment\n * routes (AGL-2980), with the member's session attached and the\n * organization named on every call. A refusal is thrown as an\n * {@link OutreachRouteError} carrying the route's own sentence, which is\n * written for the person reading it.\n */\nexport function useOutreachApi(orgId: string | null): OutreachApi {\n const { data: user } = useUser()\n\n const call = useCallback(\n async <T>(\n route: string,\n init: { method: 'GET' | 'POST'; body?: Record<string, unknown> },\n ): Promise<T> => {\n if (!orgId)\n throw new OutreachRouteError(\n 'Open an organization first.',\n 'org-required',\n 400,\n )\n const path =\n init.method === 'GET'\n ? `/api/${route}?orgId=${encodeURIComponent(orgId)}`\n : `/api/${route}`\n let response: Response\n try {\n response = await authorizedFetch(user, path, {\n method: init.method,\n ...(init.method === 'POST'\n ? {\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ orgId, ...init.body }),\n }\n : {}),\n })\n } catch {\n throw new OutreachRouteError(\n 'Sequences could not be reached. Try again.',\n 'unreachable',\n 0,\n )\n }\n const payload = (await response.json().catch(() => null)) as\n (T & { error?: undefined }) | Partial<OutreachRouteRefusal> | null\n if (!response.ok || !payload) {\n const refusal = (payload ?? {}) as Partial<OutreachRouteRefusal>\n throw new OutreachRouteError(\n refusal.error && refusal.reason\n ? refusal.error\n : response.status === 404\n ? \"Sequences isn't available to this workspace yet.\"\n : 'Sequences could not be reached. Try again.',\n refusal.reason ??\n (response.status === 404 ? 'not-found' : 'unreachable'),\n response.status,\n refusal.issues ?? [],\n )\n }\n return payload as T\n },\n [user, orgId],\n )\n\n return useMemo<OutreachApi>(\n () => ({\n readSettings: () => call(OUTREACH_API_ROUTES.settings, { method: 'GET' }),\n saveSettings: (input) =>\n call(OUTREACH_API_ROUTES.settings, {\n method: 'POST',\n body: { ...input },\n }),\n saveSequence: (sequenceId, sequence) =>\n call(OUTREACH_API_ROUTES.sequencesSave, {\n method: 'POST',\n body: { ...(sequenceId ? { sequenceId } : {}), sequence },\n }),\n setSequenceStatus: (sequenceId, action) =>\n call(OUTREACH_API_ROUTES.sequencesStatus, {\n method: 'POST',\n body: { sequenceId, action },\n }),\n deleteSequence: (sequenceId) =>\n call(OUTREACH_API_ROUTES.sequencesDelete, {\n method: 'POST',\n body: { sequenceId },\n }),\n previewEnrollment: (sequenceId, source) =>\n call(OUTREACH_API_ROUTES.enrollPreview, {\n method: 'POST',\n body: { sequenceId, source },\n }),\n enroll: (sequenceId, people) =>\n call(OUTREACH_API_ROUTES.enroll, {\n method: 'POST',\n body: { sequenceId, people },\n }),\n actOnEnrollment: (enrollmentId, action, detail) =>\n call(OUTREACH_API_ROUTES.enrollmentsAction, {\n method: 'POST',\n body: { enrollmentId, action, ...(detail ? { detail } : {}) },\n }),\n previewEmail: (input) =>\n call(OUTREACH_API_ROUTES.preview, {\n method: 'POST',\n body: { ...input },\n }),\n }),\n [call],\n )\n}\n"],"names":["authorizedFetch","useUser","useCallback","useMemo","OUTREACH_API_ROUTES","OutreachRouteError","Error","refused","reason","message","status","issues","name","useOutreachApi","orgId","data","user","call","route","init","path","method","encodeURIComponent","response","headers","body","JSON","stringify","payload","json","catch","ok","refusal","error","readSettings","settings","saveSettings","input","saveSequence","sequenceId","sequence","sequencesSave","setSequenceStatus","action","sequencesStatus","deleteSequence","sequencesDelete","previewEnrollment","source","enrollPreview","enroll","people","actOnEnrollment","enrollmentId","detail","enrollmentsAction","previewEmail","preview"],"mappings":"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"}
@@ -0,0 +1,50 @@
1
+ import type { OutreachLoad } from './use-outreach-data';
2
+ /** A saved Contacts view people can be enrolled from. */
3
+ export interface OutreachViewOption {
4
+ id: string;
5
+ name: string;
6
+ }
7
+ /** The most saved views the picker lists. */
8
+ export declare const OUTREACH_VIEWS_LIMIT = 50;
9
+ /**
10
+ * The saved Contacts views this reader may enroll from: their own and the
11
+ * shared ones — a colleague's private view is theirs — that translate whole
12
+ * into an audience. A view filtering on something enrolling cannot apply is
13
+ * not offered, because dropping that filter would enroll more people than
14
+ * the view shows.
15
+ */
16
+ export declare function useOutreachSavedViews(orgId: string | null, uid: string | null): OutreachLoad<OutreachViewOption[]>;
17
+ /** A CRM email template a step can send the body of. */
18
+ export interface OutreachTemplateOption {
19
+ id: string;
20
+ name: string;
21
+ subject: string;
22
+ body: string;
23
+ }
24
+ /**
25
+ * The CRM email templates a step at this site can use: whole letters, not
26
+ * snippets; the team's and this reader's own; written for the whole
27
+ * organization or for this site.
28
+ */
29
+ export declare function useOutreachEmailTemplates(orgId: string | null, hostId: string | null, uid: string | null): OutreachLoad<OutreachTemplateOption[]>;
30
+ /** A contact a search found. */
31
+ export interface OutreachContactOption {
32
+ id: string;
33
+ name: string;
34
+ email: string | null;
35
+ }
36
+ /** The most contacts one search answers with. */
37
+ export declare const OUTREACH_SEARCH_LIMIT = 25;
38
+ /**
39
+ * The contacts at `hostId` a search finds: by address when the text is one,
40
+ * otherwise by a word of the name — the `nameTokens` the contacts carry for
41
+ * the CRM's own search. `idle` until something is typed.
42
+ */
43
+ export declare function useOutreachContactSearch(input: {
44
+ orgId: string | null;
45
+ hostId: string | null;
46
+ contactGroupId: string | null;
47
+ text: string;
48
+ }): OutreachLoad<OutreachContactOption[]> & {
49
+ idle: boolean;
50
+ };