@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,291 @@
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 { _ as _object_without_properties_loose } from "@swc/helpers/_/_object_without_properties_loose";
19
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
20
+ import { pluginDocsHelp } from "@aglyn/aglyn";
21
+ import { CardDisplay } from "@aglyn/shared-ui-jsx";
22
+ import { useSnackbar } from "@aglyn/shared-ui-snackstack";
23
+ import { Alert, Autocomplete, Button, Chip, Paper, Stack, TextField, Typography } from "@mui/material";
24
+ import { useEffect, useMemo, useState } from "react";
25
+ import { composeOutreachFooter } from "../engine/compose.js";
26
+ import { outreachComplianceSettingsEqual, outreachCountryLabel, outreachCountryOptions, OUTREACH_BRAND_NAME_MAX, OUTREACH_LEGAL_NAME_MAX, OUTREACH_POSTAL_ADDRESS_MAX, validateOutreachComplianceSettings } from "../model/compliance-settings.js";
27
+ import { OutreachLoading, OutreachLoadProblem } from "./outreach-ui.js";
28
+ import { OutreachRouteError, useOutreachApi } from "./use-outreach-api.js";
29
+ import { useOutreachComplianceSettings } from "./use-outreach-settings.js";
30
+ /** What CAN-SPAM accepts as the postal address, as the field says it. */ export const OUTREACH_POSTAL_ADDRESS_HELP = 'A street address, a post office box registered with the US Postal Service, or a private mailbox ' + 'registered with the US Postal Service. Every email prints it in its footer.';
31
+ const EMPTY = {
32
+ legalName: '',
33
+ brandName: '',
34
+ postalAddress: '',
35
+ allowedCountries: [
36
+ 'US'
37
+ ]
38
+ };
39
+ /**
40
+ * Sequences → Compliance (AGL-2980): who every email says sent it, and the
41
+ * countries a sequence may send to at all.
42
+ *
43
+ * The footer is previewed from what is typed, by the engine's own
44
+ * `composeOutreachFooter`, so the page shows the lines every email will end
45
+ * with — or, while the legal name or the address is empty, the sentence
46
+ * that explains why nothing can be sent and no sequence activated.
47
+ */ export function OutreachComplianceSection(props) {
48
+ var _fieldIssue, _fieldIssue1, _fieldIssue2;
49
+ const { orgId } = props;
50
+ const api = useOutreachApi(orgId);
51
+ const loaded = useOutreachComplianceSettings(api, orgId);
52
+ const { enqueueSnackbar } = useSnackbar();
53
+ const [form, setForm] = useState(EMPTY);
54
+ const [saving, setSaving] = useState(false);
55
+ const [serverIssues, setServerIssues] = useState({});
56
+ const countries = useMemo(()=>outreachCountryOptions(), []);
57
+ const stored = loaded.settings;
58
+ useEffect(()=>{
59
+ if (stored) setForm(_extends({}, stored));
60
+ }, [
61
+ stored
62
+ ]);
63
+ const { settings: normalized, issues } = validateOutreachComplianceSettings(form);
64
+ const fieldIssue = (field)=>{
65
+ var _serverIssues_field;
66
+ var _issues_find;
67
+ return (_serverIssues_field = serverIssues[field]) != null ? _serverIssues_field : (_issues_find = issues.find((issue)=>issue.field === field)) == null ? void 0 : _issues_find.message;
68
+ };
69
+ const dirty = stored ? !outreachComplianceSettingsEqual(stored, normalized) : false;
70
+ const footer = composeOutreachFooter(normalized);
71
+ const set = (field)=>(value)=>{
72
+ setServerIssues({});
73
+ setForm((previous)=>_extends({}, previous, {
74
+ [field]: value
75
+ }));
76
+ };
77
+ const save = async ()=>{
78
+ setSaving(true);
79
+ try {
80
+ const answer = await api.saveSettings(normalized);
81
+ setServerIssues({});
82
+ setForm(_extends({}, answer.settings));
83
+ loaded.reload();
84
+ enqueueSnackbar(answer.changed ? 'Compliance settings saved.' : 'Nothing changed.', {
85
+ variant: answer.changed ? 'success' : 'info'
86
+ });
87
+ } catch (error) {
88
+ if (error instanceof OutreachRouteError && error.issues.length) {
89
+ setServerIssues(Object.fromEntries(error.issues.filter((issue)=>'field' in issue).map((issue)=>[
90
+ issue.field,
91
+ issue.message
92
+ ])));
93
+ }
94
+ enqueueSnackbar(error.message, {
95
+ variant: 'error',
96
+ allowDuplicate: true
97
+ });
98
+ } finally{
99
+ setSaving(false);
100
+ }
101
+ };
102
+ if (loaded.status === 'loading' || !orgId && !stored) {
103
+ return /*#__PURE__*/ _jsx(OutreachLoading, {
104
+ label: "Loading compliance settings…"
105
+ });
106
+ }
107
+ if (loaded.status === 'error' || loaded.status === 'refused') {
108
+ return /*#__PURE__*/ _jsx(OutreachLoadProblem, {
109
+ status: loaded.status,
110
+ what: "compliance settings",
111
+ message: loaded.message,
112
+ onRetry: loaded.reload
113
+ });
114
+ }
115
+ const selectedCountries = form.allowedCountries.map((code)=>{
116
+ var _countries_find;
117
+ return (_countries_find = countries.find((option)=>option.code === code)) != null ? _countries_find : {
118
+ code,
119
+ name: outreachCountryLabel(code)
120
+ };
121
+ });
122
+ return /*#__PURE__*/ _jsxs(Stack, {
123
+ spacing: 2,
124
+ children: [
125
+ /*#__PURE__*/ _jsx(CardDisplay, {
126
+ header: "Sender identity",
127
+ help: pluginDocsHelp('sequences', {
128
+ anchor: '#compliance-settings'
129
+ }),
130
+ contentGutterX: true,
131
+ contentGutterY: true,
132
+ children: /*#__PURE__*/ _jsxs(Stack, {
133
+ spacing: 2,
134
+ children: [
135
+ /*#__PURE__*/ _jsx(Typography, {
136
+ variant: "body2",
137
+ color: "text.secondary",
138
+ children: 'Every email a sequence sends ends with a footer naming your organization, its postal ' + 'address, that the email is a business solicitation, and how to stop more of them. The law ' + 'requires these on commercial email, so every email gets the footer automatically.'
139
+ }),
140
+ /*#__PURE__*/ _jsx(TextField, {
141
+ label: "Legal name",
142
+ value: form.legalName,
143
+ onChange: (event)=>set('legalName')(event.target.value),
144
+ error: Boolean(fieldIssue('legalName')),
145
+ helperText: (_fieldIssue = fieldIssue('legalName')) != null ? _fieldIssue : 'Your organization’s legal name, as the footer prints it.',
146
+ slotProps: {
147
+ htmlInput: {
148
+ maxLength: OUTREACH_LEGAL_NAME_MAX + 20
149
+ }
150
+ },
151
+ fullWidth: true
152
+ }),
153
+ /*#__PURE__*/ _jsx(TextField, {
154
+ label: "Brand name",
155
+ value: form.brandName,
156
+ onChange: (event)=>set('brandName')(event.target.value),
157
+ error: Boolean(fieldIssue('brandName')),
158
+ helperText: (_fieldIssue1 = fieldIssue('brandName')) != null ? _fieldIssue1 : 'The name the solicitation sentence uses. Leave empty to use the legal name.',
159
+ slotProps: {
160
+ htmlInput: {
161
+ maxLength: OUTREACH_BRAND_NAME_MAX + 20
162
+ }
163
+ },
164
+ fullWidth: true
165
+ }),
166
+ /*#__PURE__*/ _jsx(TextField, {
167
+ label: "Postal address",
168
+ value: form.postalAddress,
169
+ onChange: (event)=>set('postalAddress')(event.target.value),
170
+ error: Boolean(fieldIssue('postalAddress')),
171
+ helperText: (_fieldIssue2 = fieldIssue('postalAddress')) != null ? _fieldIssue2 : OUTREACH_POSTAL_ADDRESS_HELP,
172
+ slotProps: {
173
+ htmlInput: {
174
+ maxLength: OUTREACH_POSTAL_ADDRESS_MAX + 40
175
+ }
176
+ },
177
+ multiline: true,
178
+ minRows: 3,
179
+ fullWidth: true
180
+ }),
181
+ footer.footer ? /*#__PURE__*/ _jsxs(Stack, {
182
+ spacing: 0.5,
183
+ children: [
184
+ /*#__PURE__*/ _jsx(Typography, {
185
+ variant: "subtitle2",
186
+ children: "Every email ends with"
187
+ }),
188
+ /*#__PURE__*/ _jsx(Paper, {
189
+ variant: "outlined",
190
+ sx: {
191
+ p: 1.5
192
+ },
193
+ children: /*#__PURE__*/ _jsx(Typography, {
194
+ variant: "body2",
195
+ sx: {
196
+ whiteSpace: 'pre-wrap',
197
+ wordBreak: 'break-word'
198
+ },
199
+ "data-testid": "outreach-footer-preview",
200
+ children: footer.footer
201
+ })
202
+ })
203
+ ]
204
+ }) : /*#__PURE__*/ _jsx(Alert, {
205
+ severity: "warning",
206
+ children: 'No sequence can be activated, and no email sent, until you add your organization’s legal ' + 'name and postal address.'
207
+ })
208
+ ]
209
+ })
210
+ }),
211
+ /*#__PURE__*/ _jsx(CardDisplay, {
212
+ header: "Allowed countries",
213
+ help: pluginDocsHelp('sequences', {
214
+ anchor: '#allowed-countries'
215
+ }),
216
+ contentGutterX: true,
217
+ contentGutterY: true,
218
+ children: /*#__PURE__*/ _jsxs(Stack, {
219
+ spacing: 2,
220
+ children: [
221
+ /*#__PURE__*/ _jsx(Typography, {
222
+ variant: "body2",
223
+ color: "text.secondary",
224
+ children: 'Sequences may send only to people in these countries, and every sequence only to the ones ' + 'it and this list both allow. The United States is the default: Canada, the United Kingdom and most ' + 'of the European Union require a consent basis that an email to someone who never contacted ' + 'you does not have, so a cold email never goes outside the United States whatever this list ' + 'says. Add another country only for people who came to you first.'
225
+ }),
226
+ /*#__PURE__*/ _jsx(Autocomplete, {
227
+ multiple: true,
228
+ options: countries,
229
+ value: selectedCountries,
230
+ getOptionLabel: (option)=>option.name,
231
+ isOptionEqualToValue: (option, value)=>option.code === value.code,
232
+ onChange: (_event, next)=>{
233
+ setServerIssues({});
234
+ setForm((previous)=>_extends({}, previous, {
235
+ allowedCountries: next.map((option)=>option.code)
236
+ }));
237
+ },
238
+ renderValue: (value, getItemProps)=>value.map((option, index)=>{
239
+ const _getItemProps = getItemProps({
240
+ index
241
+ }), { key } = _getItemProps, item = _object_without_properties_loose(_getItemProps, [
242
+ "key"
243
+ ]);
244
+ return /*#__PURE__*/ _jsx(Chip, _extends({
245
+ size: "small",
246
+ label: option.name
247
+ }, item), key);
248
+ }),
249
+ renderInput: (params)=>/*#__PURE__*/ _jsx(TextField, _extends({}, params, {
250
+ label: "Countries",
251
+ error: Boolean(fieldIssue('allowedCountries')),
252
+ helperText: fieldIssue('allowedCountries')
253
+ }))
254
+ })
255
+ ]
256
+ })
257
+ }),
258
+ /*#__PURE__*/ _jsxs(Stack, {
259
+ direction: {
260
+ xs: 'column',
261
+ sm: 'row'
262
+ },
263
+ spacing: 1,
264
+ sx: {
265
+ justifyContent: 'flex-end'
266
+ },
267
+ children: [
268
+ /*#__PURE__*/ _jsx(Button, {
269
+ variant: "text",
270
+ disabled: !dirty || saving,
271
+ onClick: ()=>{
272
+ setServerIssues({});
273
+ if (stored) setForm(_extends({}, stored));
274
+ },
275
+ children: "Discard changes"
276
+ }),
277
+ /*#__PURE__*/ _jsx(Button, {
278
+ variant: "contained",
279
+ disabled: !dirty || saving || issues.length > 0,
280
+ onClick: ()=>void save(),
281
+ children: saving ? 'Saving…' : 'Save'
282
+ })
283
+ ]
284
+ })
285
+ ]
286
+ });
287
+ }
288
+ OutreachComplianceSection.displayName = 'OutreachComplianceSection';
289
+ export default OutreachComplianceSection;
290
+
291
+ //# sourceMappingURL=compliance-section.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../../../libs/plugins/outreach/src/lib/components/compliance-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 } from '@aglyn/aglyn'\nimport { CardDisplay } from '@aglyn/shared-ui-jsx'\nimport { useSnackbar } from '@aglyn/shared-ui-snackstack'\nimport {\n Alert,\n Autocomplete,\n Button,\n Chip,\n Paper,\n Stack,\n TextField,\n Typography,\n} from '@mui/material'\nimport { useEffect, useMemo, useState } from 'react'\nimport { composeOutreachFooter } from '../engine/compose'\nimport {\n outreachComplianceSettingsEqual,\n outreachCountryLabel,\n outreachCountryOptions,\n OUTREACH_BRAND_NAME_MAX,\n OUTREACH_LEGAL_NAME_MAX,\n OUTREACH_POSTAL_ADDRESS_MAX,\n validateOutreachComplianceSettings,\n type OutreachComplianceField,\n type OutreachCountryOption,\n} from '../model/compliance-settings'\nimport type { OutreachComplianceSettings } from '../model/outreach.types'\nimport { OutreachLoading, OutreachLoadProblem } from './outreach-ui'\nimport { OutreachRouteError, useOutreachApi } from './use-outreach-api'\nimport { useOutreachComplianceSettings } from './use-outreach-settings'\n\nexport interface OutreachComplianceSectionProps {\n /** The organization the hub is mounted under; `null` until the shell knows it. */\n orgId: string | null\n}\n\n/** What CAN-SPAM accepts as the postal address, as the field says it. */\nexport const OUTREACH_POSTAL_ADDRESS_HELP =\n 'A street address, a post office box registered with the US Postal Service, or a private mailbox ' +\n 'registered with the US Postal Service. Every email prints it in its footer.'\n\nconst EMPTY: OutreachComplianceSettings = {\n legalName: '',\n brandName: '',\n postalAddress: '',\n allowedCountries: ['US'],\n}\n\n/**\n * Sequences → Compliance (AGL-2980): who every email says sent it, and the\n * countries a sequence may send to at all.\n *\n * The footer is previewed from what is typed, by the engine's own\n * `composeOutreachFooter`, so the page shows the lines every email will end\n * with — or, while the legal name or the address is empty, the sentence\n * that explains why nothing can be sent and no sequence activated.\n */\nexport function OutreachComplianceSection(\n props: OutreachComplianceSectionProps,\n) {\n const { orgId } = props\n const api = useOutreachApi(orgId)\n const loaded = useOutreachComplianceSettings(api, orgId)\n const { enqueueSnackbar } = useSnackbar()\n const [form, setForm] = useState<OutreachComplianceSettings>(EMPTY)\n const [saving, setSaving] = useState(false)\n const [serverIssues, setServerIssues] = useState<\n Partial<Record<OutreachComplianceField, string>>\n >({})\n const countries = useMemo(() => outreachCountryOptions(), [])\n\n const stored = loaded.settings\n useEffect(() => {\n if (stored) setForm({ ...stored })\n }, [stored])\n\n const { settings: normalized, issues } =\n validateOutreachComplianceSettings(form)\n const fieldIssue = (field: OutreachComplianceField) =>\n serverIssues[field] ??\n issues.find((issue) => issue.field === field)?.message\n const dirty = stored\n ? !outreachComplianceSettingsEqual(stored, normalized)\n : false\n const footer = composeOutreachFooter(normalized)\n const set = (field: keyof OutreachComplianceSettings) => (value: string) => {\n setServerIssues({})\n setForm((previous) => ({ ...previous, [field]: value }))\n }\n\n const save = async () => {\n setSaving(true)\n try {\n const answer = await api.saveSettings(normalized)\n setServerIssues({})\n setForm({ ...answer.settings })\n loaded.reload()\n enqueueSnackbar(\n answer.changed ? 'Compliance settings saved.' : 'Nothing changed.',\n {\n variant: answer.changed ? 'success' : 'info',\n },\n )\n } catch (error) {\n if (error instanceof OutreachRouteError && error.issues.length) {\n setServerIssues(\n Object.fromEntries(\n error.issues\n .filter(\n (\n issue,\n ): issue is {\n field: OutreachComplianceField\n message: string\n } => 'field' in issue,\n )\n .map((issue) => [issue.field, issue.message]),\n ),\n )\n }\n enqueueSnackbar((error as Error).message, {\n variant: 'error',\n allowDuplicate: true,\n })\n } finally {\n setSaving(false)\n }\n }\n\n if (loaded.status === 'loading' || (!orgId && !stored)) {\n return <OutreachLoading label=\"Loading compliance settings…\" />\n }\n if (loaded.status === 'error' || loaded.status === 'refused') {\n return (\n <OutreachLoadProblem\n status={loaded.status}\n what=\"compliance settings\"\n message={loaded.message}\n onRetry={loaded.reload}\n />\n )\n }\n\n const selectedCountries = form.allowedCountries.map(\n (code) =>\n countries.find((option) => option.code === code) ?? {\n code,\n name: outreachCountryLabel(code),\n },\n )\n\n return (\n <Stack spacing={2}>\n <CardDisplay\n header=\"Sender identity\"\n help={pluginDocsHelp('sequences', { anchor: '#compliance-settings' })}\n contentGutterX\n contentGutterY\n >\n <Stack spacing={2}>\n <Typography variant=\"body2\" color=\"text.secondary\">\n {'Every email a sequence sends ends with a footer naming your organization, its postal ' +\n 'address, that the email is a business solicitation, and how to stop more of them. The law ' +\n 'requires these on commercial email, so every email gets the footer automatically.'}\n </Typography>\n <TextField\n label=\"Legal name\"\n value={form.legalName}\n onChange={(event) => set('legalName')(event.target.value)}\n error={Boolean(fieldIssue('legalName'))}\n helperText={\n fieldIssue('legalName') ??\n 'Your organization’s legal name, as the footer prints it.'\n }\n slotProps={{\n htmlInput: { maxLength: OUTREACH_LEGAL_NAME_MAX + 20 },\n }}\n fullWidth\n />\n <TextField\n label=\"Brand name\"\n value={form.brandName}\n onChange={(event) => set('brandName')(event.target.value)}\n error={Boolean(fieldIssue('brandName'))}\n helperText={\n fieldIssue('brandName') ??\n 'The name the solicitation sentence uses. Leave empty to use the legal name.'\n }\n slotProps={{\n htmlInput: { maxLength: OUTREACH_BRAND_NAME_MAX + 20 },\n }}\n fullWidth\n />\n <TextField\n label=\"Postal address\"\n value={form.postalAddress}\n onChange={(event) => set('postalAddress')(event.target.value)}\n error={Boolean(fieldIssue('postalAddress'))}\n helperText={\n fieldIssue('postalAddress') ?? OUTREACH_POSTAL_ADDRESS_HELP\n }\n slotProps={{\n htmlInput: { maxLength: OUTREACH_POSTAL_ADDRESS_MAX + 40 },\n }}\n multiline\n minRows={3}\n fullWidth\n />\n {footer.footer ? (\n <Stack spacing={0.5}>\n <Typography variant=\"subtitle2\">Every email ends with</Typography>\n <Paper variant=\"outlined\" sx={{ p: 1.5 }}>\n <Typography\n variant=\"body2\"\n sx={{ whiteSpace: 'pre-wrap', wordBreak: 'break-word' }}\n data-testid=\"outreach-footer-preview\"\n >\n {footer.footer}\n </Typography>\n </Paper>\n </Stack>\n ) : (\n <Alert severity=\"warning\">\n {'No sequence can be activated, and no email sent, until you add your organization’s legal ' +\n 'name and postal address.'}\n </Alert>\n )}\n </Stack>\n </CardDisplay>\n\n <CardDisplay\n header=\"Allowed countries\"\n help={pluginDocsHelp('sequences', { anchor: '#allowed-countries' })}\n contentGutterX\n contentGutterY\n >\n <Stack spacing={2}>\n <Typography variant=\"body2\" color=\"text.secondary\">\n {'Sequences may send only to people in these countries, and every sequence only to the ones ' +\n 'it and this list both allow. The United States is the default: Canada, the United Kingdom and most ' +\n 'of the European Union require a consent basis that an email to someone who never contacted ' +\n 'you does not have, so a cold email never goes outside the United States whatever this list ' +\n 'says. Add another country only for people who came to you first.'}\n </Typography>\n <Autocomplete<OutreachCountryOption, true>\n multiple\n options={countries}\n value={selectedCountries}\n getOptionLabel={(option) => option.name}\n isOptionEqualToValue={(option, value) => option.code === value.code}\n onChange={(_event, next) => {\n setServerIssues({})\n setForm((previous) => ({\n ...previous,\n allowedCountries: next.map((option) => option.code),\n }))\n }}\n renderValue={(value, getItemProps) =>\n value.map((option, index) => {\n const { key, ...item } = getItemProps({ index })\n return (\n <Chip key={key} size=\"small\" label={option.name} {...item} />\n )\n })\n }\n renderInput={(params) => (\n <TextField\n {...params}\n label=\"Countries\"\n error={Boolean(fieldIssue('allowedCountries'))}\n helperText={fieldIssue('allowedCountries')}\n />\n )}\n />\n </Stack>\n </CardDisplay>\n\n <Stack\n direction={{ xs: 'column', sm: 'row' }}\n spacing={1}\n sx={{ justifyContent: 'flex-end' }}\n >\n <Button\n variant=\"text\"\n disabled={!dirty || saving}\n onClick={() => {\n setServerIssues({})\n if (stored) setForm({ ...stored })\n }}\n >\n Discard changes\n </Button>\n <Button\n variant=\"contained\"\n disabled={!dirty || saving || issues.length > 0}\n onClick={() => void save()}\n >\n {saving ? 'Saving…' : 'Save'}\n </Button>\n </Stack>\n </Stack>\n )\n}\nOutreachComplianceSection.displayName = 'OutreachComplianceSection'\n\nexport default OutreachComplianceSection\n"],"names":["pluginDocsHelp","CardDisplay","useSnackbar","Alert","Autocomplete","Button","Chip","Paper","Stack","TextField","Typography","useEffect","useMemo","useState","composeOutreachFooter","outreachComplianceSettingsEqual","outreachCountryLabel","outreachCountryOptions","OUTREACH_BRAND_NAME_MAX","OUTREACH_LEGAL_NAME_MAX","OUTREACH_POSTAL_ADDRESS_MAX","validateOutreachComplianceSettings","OutreachLoading","OutreachLoadProblem","OutreachRouteError","useOutreachApi","useOutreachComplianceSettings","OUTREACH_POSTAL_ADDRESS_HELP","EMPTY","legalName","brandName","postalAddress","allowedCountries","OutreachComplianceSection","props","fieldIssue","orgId","api","loaded","enqueueSnackbar","form","setForm","saving","setSaving","serverIssues","setServerIssues","countries","stored","settings","normalized","issues","field","find","issue","message","dirty","footer","set","value","previous","save","answer","saveSettings","reload","changed","variant","error","length","Object","fromEntries","filter","map","allowDuplicate","status","label","what","onRetry","selectedCountries","code","option","name","spacing","header","help","anchor","contentGutterX","contentGutterY","color","onChange","event","target","Boolean","helperText","slotProps","htmlInput","maxLength","fullWidth","multiline","minRows","sx","p","whiteSpace","wordBreak","data-testid","severity","multiple","options","getOptionLabel","isOptionEqualToValue","_event","next","renderValue","getItemProps","index","key","item","size","renderInput","params","direction","xs","sm","justifyContent","disabled","onClick","displayName"],"mappings":"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"}
@@ -0,0 +1,36 @@
1
+ import { type OutreachEnrollPreviewPerson } from '../model/outreach-api';
2
+ import { type OutreachAttestationKind, type OutreachSequence } from '../model/outreach.types';
3
+ import type { OutreachApi } from './use-outreach-api';
4
+ export interface OutreachEnrollDialogProps {
5
+ open: boolean;
6
+ onClose(): void;
7
+ orgId: string;
8
+ sequence: OutreachSequence;
9
+ /** The consent group of the sequence's site: whose names a search shows. */
10
+ contactGroupId: string;
11
+ uid: string | null;
12
+ api: OutreachApi;
13
+ }
14
+ /** What the rep has supplied for one person. */
15
+ interface Supplied {
16
+ include: boolean;
17
+ personalLine: string;
18
+ attestations: OutreachAttestationKind[];
19
+ }
20
+ /** Whether a person may be sent to Confirm as the rep has left them. */
21
+ export declare function outreachPersonReady(person: OutreachEnrollPreviewPerson, supplied: Supplied | undefined): boolean;
22
+ /**
23
+ * Enroll people in a sequence (AGL-2980).
24
+ *
25
+ * The rep picks a saved Contacts view or searches for people, and sees each
26
+ * marked as the gates see them: eligible, blocked with the reason, or
27
+ * waiting on them — for a cold contact, a personal line and the three
28
+ * attestations only they can make, stored on the enrollment with who ticked
29
+ * them and when. Enroll sends only the people who are ready, and the server
30
+ * checks every gate again as it enrolls them.
31
+ */
32
+ export declare function OutreachEnrollDialog(props: OutreachEnrollDialogProps): import("react").JSX.Element;
33
+ export declare namespace OutreachEnrollDialog {
34
+ var displayName: string;
35
+ }
36
+ export default OutreachEnrollDialog;