@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,485 @@
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 { mdiPlus } from "@aglyn/shared-data-mdi";
22
+ import { CardDisplay, MdiIcon } from "@aglyn/shared-ui-jsx";
23
+ import { useSnackbar } from "@aglyn/shared-ui-snackstack";
24
+ import { useUser } from "@aglyn/tenant-feature-instance";
25
+ import { Alert, Autocomplete, Box, Button, Chip, FormControlLabel, Grid, Menu, MenuItem, Stack, Switch, TextField, Typography } from "@mui/material";
26
+ import { useEffect, useMemo, useState } from "react";
27
+ import { isInThreadEmailStep, OUTREACH_SEQUENCE_NAME_MAX, validateOutreachSequence } from "../engine/sequence-validation.js";
28
+ import { outreachCountryLabel } from "../model/compliance-settings.js";
29
+ import { OUTREACH_MAX_EMAIL_STEPS, OUTREACH_MAX_STEPS, OUTREACH_TASK_KIND_LABELS, OUTREACH_TASK_KINDS } from "../model/outreach.types.js";
30
+ import { emptyOutreachSequenceDraft, newOutreachEmailStep, newOutreachTaskStep, outreachSequenceDraftOf } from "../model/sequence-draft.js";
31
+ import { OutreachSendWindowFields } from "./send-window-fields.js";
32
+ import { OutreachSequenceMailboxPicker } from "./sequence-mailbox-picker.js";
33
+ import { OutreachSequencePreview } from "./sequence-preview.js";
34
+ import { OutreachStepCard } from "./sequence-step-card.js";
35
+ import { OutreachRouteError, useOutreachApi } from "./use-outreach-api.js";
36
+ import { useOutreachEmailTemplates } from "./use-outreach-crm.js";
37
+ /** The step a dotted issue path is about, and the field within it. */ function stepIssueKey(path) {
38
+ var _match_;
39
+ const match = /^steps\.(\d+)(?:\.(.+))?$/.exec(path);
40
+ if (!match) return null;
41
+ const field = (_match_ = match[2]) != null ? _match_ : 'step';
42
+ return {
43
+ index: Number(match[1]),
44
+ field: field === 'id' ? 'step' : field
45
+ };
46
+ }
47
+ /**
48
+ * The sequence editor (AGL-2980): the name, the site and mailbox, the steps,
49
+ * who it sends to and when, beside a live preview of each email.
50
+ *
51
+ * Every issue the engine's validator finds is shown beside its field — the
52
+ * same validator the save route refuses with — errors once a save was
53
+ * attempted, warnings as soon as they appear. What only the server can
54
+ * judge (whose mailbox, which countries the organization allows, what may
55
+ * no longer change once people are enrolled) comes back from the save and
56
+ * is shown in the same places.
57
+ */ export function OutreachSequenceEditor(props) {
58
+ var _ref, _ref1, _props_mailboxes_mailboxes_find, _ref2, _issueAt;
59
+ var _settings_settings, _settings_settings1, _issues_find, _hosts_find;
60
+ const { orgId, orgMount, sequence, settings } = props;
61
+ const api = useOutreachApi(orgId);
62
+ const { enqueueSnackbar } = useSnackbar();
63
+ const { data: user } = useUser();
64
+ const uid = (_ref = user == null ? void 0 : user.uid) != null ? _ref : null;
65
+ const mountedHosts = orgMount == null ? void 0 : orgMount.hosts;
66
+ const hosts = useMemo(()=>mountedHosts != null ? mountedHosts : [], [
67
+ mountedHosts
68
+ ]);
69
+ const orgCountries = (_ref1 = (_settings_settings = settings.settings) == null ? void 0 : _settings_settings.allowedCountries) != null ? _ref1 : [
70
+ 'US'
71
+ ];
72
+ const [draft, setDraft] = useState(()=>sequence ? outreachSequenceDraftOf(sequence) : emptyOutreachSequenceDraft({
73
+ hostId: hosts.length === 1 ? hosts[0].id : '',
74
+ allowedCountries: orgCountries
75
+ }));
76
+ const [attempted, setAttempted] = useState(false);
77
+ const [serverIssues, setServerIssues] = useState([]);
78
+ const [saving, setSaving] = useState(false);
79
+ const [taskAnchor, setTaskAnchor] = useState(null);
80
+ // A stored sequence the listener updated (a save, a status change) is the
81
+ // new starting point.
82
+ useEffect(()=>{
83
+ if (sequence) setDraft(outreachSequenceDraftOf(sequence));
84
+ }, [
85
+ sequence
86
+ ]);
87
+ // A new sequence starts on the organization's countries once they are read.
88
+ const settingsCountries = (_settings_settings1 = settings.settings) == null ? void 0 : _settings_settings1.allowedCountries.join(',');
89
+ useEffect(()=>{
90
+ if (!sequence && settingsCountries) {
91
+ setDraft((previous)=>_extends({}, previous, {
92
+ settings: _extends({}, previous.settings, {
93
+ allowedCountries: settingsCountries.split(',')
94
+ })
95
+ }));
96
+ }
97
+ }, [
98
+ sequence,
99
+ settingsCountries
100
+ ]);
101
+ useEffect(()=>{
102
+ if (!sequence && !draft.hostId && hosts.length === 1) setDraft((previous)=>_extends({}, previous, {
103
+ hostId: hosts[0].id
104
+ }));
105
+ }, [
106
+ sequence,
107
+ draft.hostId,
108
+ hosts
109
+ ]);
110
+ // A new sequence starts on the member's own mailbox when they have exactly
111
+ // one that is sending.
112
+ const ownSending = props.mailboxes.mailboxes.filter((entry)=>entry.connectedByUid === uid && entry.status === 'connected');
113
+ const onlyOwnMailbox = ownSending.length === 1 ? ownSending[0].id : '';
114
+ useEffect(()=>{
115
+ if (!sequence && !draft.mailboxId && onlyOwnMailbox) setDraft((previous)=>_extends({}, previous, {
116
+ mailboxId: onlyOwnMailbox
117
+ }));
118
+ }, [
119
+ sequence,
120
+ draft.mailboxId,
121
+ onlyOwnMailbox
122
+ ]);
123
+ const templates = useOutreachEmailTemplates(orgId, draft.hostId || null, uid);
124
+ const mailbox = (_props_mailboxes_mailboxes_find = props.mailboxes.mailboxes.find((entry)=>entry.id === draft.mailboxId)) != null ? _props_mailboxes_mailboxes_find : null;
125
+ const archived = (sequence == null ? void 0 : sequence.status) === 'archived';
126
+ const issues = useMemo(()=>{
127
+ const judged = [
128
+ ...validateOutreachSequence(draft),
129
+ ...serverIssues
130
+ ];
131
+ return judged.filter((issue)=>issue.severity === 'warning' || attempted || serverIssues.includes(issue));
132
+ }, [
133
+ draft,
134
+ serverIssues,
135
+ attempted
136
+ ]);
137
+ const issueAt = (path)=>{
138
+ var _issues_find;
139
+ return (_issues_find = issues.find((issue)=>issue.path === path)) == null ? void 0 : _issues_find.message;
140
+ };
141
+ const stepIssues = (index)=>{
142
+ const found = {};
143
+ for (const issue of issues){
144
+ const key = stepIssueKey(issue.path);
145
+ if ((key == null ? void 0 : key.index) === index && !found[key.field]) found[key.field] = issue.message;
146
+ }
147
+ return found;
148
+ };
149
+ const listIssue = issueAt('steps');
150
+ const countriesIssue = (_issues_find = issues.find((issue)=>issue.path.startsWith('settings.allowedCountries'))) == null ? void 0 : _issues_find.message;
151
+ const update = (next)=>{
152
+ setServerIssues([]);
153
+ setDraft((previous)=>_extends({}, previous, next));
154
+ };
155
+ const setStep = (index, step)=>update({
156
+ steps: draft.steps.map((entry, position)=>position === index ? step : entry)
157
+ });
158
+ const moveStep = (index, direction)=>{
159
+ const steps = [
160
+ ...draft.steps
161
+ ];
162
+ const [moved] = steps.splice(index, 1);
163
+ steps.splice(index + direction, 0, moved);
164
+ update({
165
+ steps
166
+ });
167
+ };
168
+ const emailCount = draft.steps.filter((step)=>step.kind === 'email').length;
169
+ const full = draft.steps.length >= OUTREACH_MAX_STEPS;
170
+ const threadSubject = (index)=>{
171
+ for(let position = index - 1; position >= 0; position -= 1){
172
+ const step = draft.steps[position];
173
+ if (step.kind === 'email' && !isInThreadEmailStep(draft.steps, position)) return step.subject;
174
+ }
175
+ return '';
176
+ };
177
+ const save = async ()=>{
178
+ setAttempted(true);
179
+ if (validateOutreachSequence(draft).some((issue)=>issue.severity === 'error')) return;
180
+ setSaving(true);
181
+ try {
182
+ var _ref;
183
+ const answer = await api.saveSequence((_ref = sequence == null ? void 0 : sequence.id) != null ? _ref : null, draft);
184
+ setServerIssues([]);
185
+ setAttempted(false);
186
+ enqueueSnackbar(answer.created ? 'Sequence created.' : 'Sequence saved.', {
187
+ variant: 'success'
188
+ });
189
+ props.onSaved(answer.sequence);
190
+ } catch (error) {
191
+ if (error instanceof OutreachRouteError && error.issues.length) {
192
+ setServerIssues(error.issues.filter((issue)=>'path' in issue));
193
+ }
194
+ enqueueSnackbar(error.message, {
195
+ variant: 'error',
196
+ allowDuplicate: true
197
+ });
198
+ } finally{
199
+ setSaving(false);
200
+ }
201
+ };
202
+ const siteName = (_ref2 = (_hosts_find = hosts.find((host)=>host.id === draft.hostId)) == null ? void 0 : _hosts_find.name) != null ? _ref2 : '';
203
+ const countryOptions = [
204
+ ...new Set([
205
+ ...orgCountries,
206
+ ...draft.settings.allowedCountries
207
+ ])
208
+ ];
209
+ return /*#__PURE__*/ _jsxs(Grid, {
210
+ container: true,
211
+ spacing: 2,
212
+ children: [
213
+ /*#__PURE__*/ _jsx(Grid, {
214
+ size: {
215
+ xs: 12,
216
+ md: 7
217
+ },
218
+ children: /*#__PURE__*/ _jsxs(Stack, {
219
+ spacing: 2,
220
+ children: [
221
+ archived ? /*#__PURE__*/ _jsx(Alert, {
222
+ severity: "info",
223
+ children: "This sequence is archived, so it can’t be edited."
224
+ }) : null,
225
+ /*#__PURE__*/ _jsx(CardDisplay, {
226
+ header: "Sequence",
227
+ help: pluginDocsHelp('sequences', {
228
+ anchor: '#build-a-sequence'
229
+ }),
230
+ contentGutterX: true,
231
+ contentGutterY: true,
232
+ children: /*#__PURE__*/ _jsxs(Stack, {
233
+ spacing: 2,
234
+ children: [
235
+ /*#__PURE__*/ _jsx(TextField, {
236
+ label: "Name",
237
+ value: draft.name,
238
+ onChange: (event)=>update({
239
+ name: event.target.value
240
+ }),
241
+ disabled: archived,
242
+ error: Boolean(issueAt('name')),
243
+ helperText: issueAt('name'),
244
+ slotProps: {
245
+ htmlInput: {
246
+ maxLength: OUTREACH_SEQUENCE_NAME_MAX + 20
247
+ }
248
+ },
249
+ fullWidth: true
250
+ }),
251
+ /*#__PURE__*/ _jsx(TextField, {
252
+ select: true,
253
+ label: "Site",
254
+ value: hosts.some((host)=>host.id === draft.hostId) ? draft.hostId : '',
255
+ onChange: (event)=>update({
256
+ hostId: event.target.value
257
+ }),
258
+ disabled: archived || !hosts.length,
259
+ error: Boolean(issueAt('hostId')),
260
+ helperText: (_issueAt = issueAt('hostId')) != null ? _issueAt : 'The site whose contacts this sequence emails.',
261
+ fullWidth: true,
262
+ children: hosts.map((host)=>/*#__PURE__*/ _jsx(MenuItem, {
263
+ value: host.id,
264
+ children: host.name
265
+ }, host.id))
266
+ }),
267
+ /*#__PURE__*/ _jsx(OutreachSequenceMailboxPicker, {
268
+ orgId: orgId,
269
+ uid: uid,
270
+ mailboxes: props.mailboxes,
271
+ mailboxesPath: props.mailboxesPath,
272
+ value: draft.mailboxId,
273
+ onChange: (mailboxId)=>update({
274
+ mailboxId
275
+ }),
276
+ error: issueAt('mailboxId'),
277
+ disabled: archived
278
+ })
279
+ ]
280
+ })
281
+ }),
282
+ listIssue ? /*#__PURE__*/ _jsx(Alert, {
283
+ severity: "error",
284
+ children: listIssue
285
+ }) : null,
286
+ draft.steps.map((step, index)=>/*#__PURE__*/ _jsx(OutreachStepCard, {
287
+ step: step,
288
+ index: index,
289
+ count: draft.steps.length,
290
+ firstEmail: draft.steps.findIndex((entry)=>entry.kind === 'email') === index,
291
+ inThread: isInThreadEmailStep(draft.steps, index),
292
+ threadSubject: threadSubject(index),
293
+ templates: templates.data,
294
+ issues: stepIssues(index),
295
+ disabled: archived,
296
+ onChange: (next)=>setStep(index, next),
297
+ onMove: (direction)=>moveStep(index, direction),
298
+ onRemove: ()=>update({
299
+ steps: draft.steps.filter((_entry, position)=>position !== index)
300
+ })
301
+ }, step.id || `step-${index}`)),
302
+ /*#__PURE__*/ _jsxs(Stack, {
303
+ direction: "row",
304
+ spacing: 1,
305
+ sx: {
306
+ flexWrap: 'wrap',
307
+ rowGap: 1
308
+ },
309
+ children: [
310
+ /*#__PURE__*/ _jsx(Button, {
311
+ variant: "outlined",
312
+ startIcon: /*#__PURE__*/ _jsx(MdiIcon, {
313
+ path: mdiPlus.path,
314
+ fontSize: "small"
315
+ }),
316
+ disabled: archived || full || emailCount >= OUTREACH_MAX_EMAIL_STEPS,
317
+ onClick: ()=>update({
318
+ steps: [
319
+ ...draft.steps,
320
+ newOutreachEmailStep(draft.steps)
321
+ ]
322
+ }),
323
+ children: "Add email"
324
+ }),
325
+ /*#__PURE__*/ _jsx(Button, {
326
+ variant: "outlined",
327
+ startIcon: /*#__PURE__*/ _jsx(MdiIcon, {
328
+ path: mdiPlus.path,
329
+ fontSize: "small"
330
+ }),
331
+ disabled: archived || full,
332
+ onClick: (event)=>setTaskAnchor(event.currentTarget),
333
+ "aria-haspopup": "menu",
334
+ children: "Add task"
335
+ }),
336
+ /*#__PURE__*/ _jsx(Menu, {
337
+ anchorEl: taskAnchor,
338
+ open: Boolean(taskAnchor),
339
+ onClose: ()=>setTaskAnchor(null),
340
+ children: OUTREACH_TASK_KINDS.map((kind)=>/*#__PURE__*/ _jsx(MenuItem, {
341
+ onClick: ()=>{
342
+ setTaskAnchor(null);
343
+ update({
344
+ steps: [
345
+ ...draft.steps,
346
+ newOutreachTaskStep(draft.steps, kind)
347
+ ]
348
+ });
349
+ },
350
+ children: OUTREACH_TASK_KIND_LABELS[kind]
351
+ }, kind))
352
+ })
353
+ ]
354
+ }),
355
+ /*#__PURE__*/ _jsx(Typography, {
356
+ variant: "caption",
357
+ color: "text.secondary",
358
+ children: `Up to ${OUTREACH_MAX_STEPS} steps, ${OUTREACH_MAX_EMAIL_STEPS} of them emails.`
359
+ }),
360
+ /*#__PURE__*/ _jsx(CardDisplay, {
361
+ header: "Who it sends to, and when",
362
+ help: pluginDocsHelp('sequences', {
363
+ anchor: '#build-a-sequence',
364
+ excerpt: 'A sequence sends only to the countries both it and your organization allow, and in its mailbox’s sending hours unless it has its own.'
365
+ }),
366
+ contentGutterX: true,
367
+ contentGutterY: true,
368
+ children: /*#__PURE__*/ _jsxs(Stack, {
369
+ spacing: 2,
370
+ children: [
371
+ /*#__PURE__*/ _jsx(Autocomplete, {
372
+ multiple: true,
373
+ options: countryOptions,
374
+ value: draft.settings.allowedCountries,
375
+ getOptionLabel: outreachCountryLabel,
376
+ onChange: (_event, next)=>update({
377
+ settings: _extends({}, draft.settings, {
378
+ allowedCountries: next
379
+ })
380
+ }),
381
+ disabled: archived,
382
+ renderValue: (value, getItemProps)=>value.map((code, index)=>{
383
+ const _getItemProps = getItemProps({
384
+ index
385
+ }), { key } = _getItemProps, item = _object_without_properties_loose(_getItemProps, [
386
+ "key"
387
+ ]);
388
+ return /*#__PURE__*/ _jsx(Chip, _extends({
389
+ size: "small",
390
+ label: outreachCountryLabel(code)
391
+ }, item), key);
392
+ }),
393
+ renderInput: (params)=>/*#__PURE__*/ _jsx(TextField, _extends({}, params, {
394
+ label: "Countries",
395
+ error: Boolean(countriesIssue),
396
+ helperText: countriesIssue != null ? countriesIssue : 'Among the countries your organization allows. Cold contacts are emailed only in the United States.'
397
+ }))
398
+ }),
399
+ /*#__PURE__*/ _jsx(FormControlLabel, {
400
+ control: /*#__PURE__*/ _jsx(Switch, {
401
+ checked: draft.settings.allowCustomers,
402
+ onChange: (event)=>update({
403
+ settings: _extends({}, draft.settings, {
404
+ allowCustomers: event.target.checked
405
+ })
406
+ }),
407
+ disabled: archived
408
+ }),
409
+ label: "Include customers"
410
+ }),
411
+ /*#__PURE__*/ _jsx(OutreachSendWindowFields, {
412
+ window: draft.settings.window,
413
+ onChange: (window)=>update({
414
+ settings: _extends({}, draft.settings, {
415
+ window
416
+ })
417
+ }),
418
+ daysIssue: issueAt('settings.window.days'),
419
+ hoursIssue: issueAt('settings.window'),
420
+ disabled: archived
421
+ })
422
+ ]
423
+ })
424
+ }),
425
+ archived ? null : /*#__PURE__*/ _jsxs(Stack, {
426
+ direction: {
427
+ xs: 'column',
428
+ sm: 'row'
429
+ },
430
+ spacing: 1,
431
+ sx: {
432
+ justifyContent: 'flex-end'
433
+ },
434
+ children: [
435
+ props.onCancel ? /*#__PURE__*/ _jsx(Button, {
436
+ variant: "text",
437
+ onClick: props.onCancel,
438
+ disabled: saving,
439
+ children: "Cancel"
440
+ }) : null,
441
+ /*#__PURE__*/ _jsx(Button, {
442
+ variant: "contained",
443
+ onClick: ()=>void save(),
444
+ disabled: saving,
445
+ children: saving ? 'Saving…' : sequence ? 'Save' : 'Create sequence'
446
+ })
447
+ ]
448
+ })
449
+ ]
450
+ })
451
+ }),
452
+ /*#__PURE__*/ _jsx(Grid, {
453
+ size: {
454
+ xs: 12,
455
+ md: 5
456
+ },
457
+ children: /*#__PURE__*/ _jsx(Box, {
458
+ sx: {
459
+ position: {
460
+ md: 'sticky'
461
+ },
462
+ top: {
463
+ md: 16
464
+ }
465
+ },
466
+ children: /*#__PURE__*/ _jsx(OutreachSequencePreview, {
467
+ steps: draft.steps,
468
+ orgSettings: settings.settings,
469
+ orgSettingsStatus: settings.status,
470
+ templates: templates.data,
471
+ sender: mailbox ? {
472
+ name: mailbox.displayName,
473
+ email: mailbox.sendAs || mailbox.email
474
+ } : null,
475
+ siteName: siteName
476
+ })
477
+ })
478
+ })
479
+ ]
480
+ });
481
+ }
482
+ OutreachSequenceEditor.displayName = 'OutreachSequenceEditor';
483
+ export default OutreachSequenceEditor;
484
+
485
+ //# sourceMappingURL=sequence-editor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../../../libs/plugins/outreach/src/lib/components/sequence-editor.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 { useSnackbar } from '@aglyn/shared-ui-snackstack'\nimport { useUser } from '@aglyn/tenant-feature-instance'\nimport {\n Alert,\n Autocomplete,\n Box,\n Button,\n Chip,\n FormControlLabel,\n Grid,\n Menu,\n MenuItem,\n Stack,\n Switch,\n TextField,\n Typography,\n} from '@mui/material'\nimport { useEffect, useMemo, useState } from 'react'\nimport {\n isInThreadEmailStep,\n OUTREACH_SEQUENCE_NAME_MAX,\n validateOutreachSequence,\n} from '../engine/sequence-validation'\nimport { outreachCountryLabel } from '../model/compliance-settings'\nimport {\n OUTREACH_MAX_EMAIL_STEPS,\n OUTREACH_MAX_STEPS,\n OUTREACH_TASK_KIND_LABELS,\n OUTREACH_TASK_KINDS,\n type OutreachSequence,\n type OutreachSequenceStep,\n type OutreachTaskKind,\n} from '../model/outreach.types'\nimport {\n emptyOutreachSequenceDraft,\n newOutreachEmailStep,\n newOutreachTaskStep,\n outreachSequenceDraftOf,\n type OutreachSequenceDraft,\n type OutreachSequenceIssue,\n} from '../model/sequence-draft'\nimport { OutreachSendWindowFields } from './send-window-fields'\nimport { OutreachSequenceMailboxPicker } from './sequence-mailbox-picker'\nimport { OutreachSequencePreview } from './sequence-preview'\nimport { OutreachStepCard } from './sequence-step-card'\nimport { OutreachRouteError, useOutreachApi } from './use-outreach-api'\nimport { useOutreachEmailTemplates } from './use-outreach-crm'\nimport type { OutreachMailboxesResult } from './use-outreach-mailboxes'\nimport type { OutreachSettingsLoad } from './use-outreach-settings'\n\nexport interface OutreachSequenceEditorProps {\n orgId: string\n orgMount?: ConsolePluginOrgMount\n /** The stored sequence, or `null` for a new one. */\n sequence: OutreachSequence | null\n /** The organization's compliance settings: its countries, and the preview's footer. */\n settings: OutreachSettingsLoad\n /**\n * The organization's mailboxes, from the Mailboxes section's listener:\n * what the picker offers, and who the preview's emails are from.\n */\n mailboxes: OutreachMailboxesResult\n /** The Mailboxes section, where the picker sends a member to connect one. */\n mailboxesPath: string\n onSaved(sequence: OutreachSequence): void\n onCancel?(): void\n}\n\n/** The step a dotted issue path is about, and the field within it. */\nfunction stepIssueKey(path: string): { index: number; field: string } | null {\n const match = /^steps\\.(\\d+)(?:\\.(.+))?$/.exec(path)\n if (!match) return null\n const field = match[2] ?? 'step'\n return { index: Number(match[1]), field: field === 'id' ? 'step' : field }\n}\n\n/**\n * The sequence editor (AGL-2980): the name, the site and mailbox, the steps,\n * who it sends to and when, beside a live preview of each email.\n *\n * Every issue the engine's validator finds is shown beside its field — the\n * same validator the save route refuses with — errors once a save was\n * attempted, warnings as soon as they appear. What only the server can\n * judge (whose mailbox, which countries the organization allows, what may\n * no longer change once people are enrolled) comes back from the save and\n * is shown in the same places.\n */\nexport function OutreachSequenceEditor(props: OutreachSequenceEditorProps) {\n const { orgId, orgMount, sequence, settings } = props\n const api = useOutreachApi(orgId)\n const { enqueueSnackbar } = useSnackbar()\n const { data: user } = useUser()\n const uid = user?.uid ?? null\n const mountedHosts = orgMount?.hosts\n const hosts = useMemo(() => mountedHosts ?? [], [mountedHosts])\n const orgCountries = settings.settings?.allowedCountries ?? ['US']\n\n const [draft, setDraft] = useState<OutreachSequenceDraft>(() =>\n sequence\n ? outreachSequenceDraftOf(sequence)\n : emptyOutreachSequenceDraft({\n hostId: hosts.length === 1 ? hosts[0].id : '',\n allowedCountries: orgCountries,\n }),\n )\n const [attempted, setAttempted] = useState(false)\n const [serverIssues, setServerIssues] = useState<OutreachSequenceIssue[]>([])\n const [saving, setSaving] = useState(false)\n const [taskAnchor, setTaskAnchor] = useState<HTMLElement | null>(null)\n\n // A stored sequence the listener updated (a save, a status change) is the\n // new starting point.\n useEffect(() => {\n if (sequence) setDraft(outreachSequenceDraftOf(sequence))\n }, [sequence])\n // A new sequence starts on the organization's countries once they are read.\n const settingsCountries = settings.settings?.allowedCountries.join(',')\n useEffect(() => {\n if (!sequence && settingsCountries) {\n setDraft((previous) => ({\n ...previous,\n settings: {\n ...previous.settings,\n allowedCountries: settingsCountries.split(','),\n },\n }))\n }\n }, [sequence, settingsCountries])\n useEffect(() => {\n if (!sequence && !draft.hostId && hosts.length === 1)\n setDraft((previous) => ({ ...previous, hostId: hosts[0].id }))\n }, [sequence, draft.hostId, hosts])\n\n // A new sequence starts on the member's own mailbox when they have exactly\n // one that is sending.\n const ownSending = props.mailboxes.mailboxes.filter(\n (entry) => entry.connectedByUid === uid && entry.status === 'connected',\n )\n const onlyOwnMailbox = ownSending.length === 1 ? ownSending[0].id : ''\n useEffect(() => {\n if (!sequence && !draft.mailboxId && onlyOwnMailbox)\n setDraft((previous) => ({ ...previous, mailboxId: onlyOwnMailbox }))\n }, [sequence, draft.mailboxId, onlyOwnMailbox])\n\n const templates = useOutreachEmailTemplates(orgId, draft.hostId || null, uid)\n const mailbox =\n props.mailboxes.mailboxes.find((entry) => entry.id === draft.mailboxId) ??\n null\n const archived = sequence?.status === 'archived'\n\n const issues = useMemo(() => {\n const judged = [\n ...validateOutreachSequence(draft),\n ...serverIssues,\n ] as OutreachSequenceIssue[]\n return judged.filter(\n (issue) =>\n issue.severity === 'warning' ||\n attempted ||\n serverIssues.includes(issue),\n )\n }, [draft, serverIssues, attempted])\n const issueAt = (path: string) =>\n issues.find((issue) => issue.path === path)?.message\n const stepIssues = (index: number) => {\n const found: Record<string, string> = {}\n for (const issue of issues) {\n const key = stepIssueKey(issue.path)\n if (key?.index === index && !found[key.field])\n found[key.field] = issue.message\n }\n return found\n }\n const listIssue = issueAt('steps')\n const countriesIssue = issues.find((issue) =>\n issue.path.startsWith('settings.allowedCountries'),\n )?.message\n\n const update = (next: Partial<OutreachSequenceDraft>) => {\n setServerIssues([])\n setDraft((previous) => ({ ...previous, ...next }))\n }\n const setStep = (index: number, step: OutreachSequenceStep) =>\n update({\n steps: draft.steps.map((entry, position) =>\n position === index ? step : entry,\n ),\n })\n const moveStep = (index: number, direction: -1 | 1) => {\n const steps = [...draft.steps]\n const [moved] = steps.splice(index, 1)\n steps.splice(index + direction, 0, moved)\n update({ steps })\n }\n const emailCount = draft.steps.filter((step) => step.kind === 'email').length\n const full = draft.steps.length >= OUTREACH_MAX_STEPS\n const threadSubject = (index: number) => {\n for (let position = index - 1; position >= 0; position -= 1) {\n const step = draft.steps[position]\n if (step.kind === 'email' && !isInThreadEmailStep(draft.steps, position))\n return step.subject\n }\n return ''\n }\n\n const save = async () => {\n setAttempted(true)\n if (\n validateOutreachSequence(draft).some(\n (issue) => issue.severity === 'error',\n )\n )\n return\n setSaving(true)\n try {\n const answer = await api.saveSequence(sequence?.id ?? null, draft)\n setServerIssues([])\n setAttempted(false)\n enqueueSnackbar(\n answer.created ? 'Sequence created.' : 'Sequence saved.',\n { variant: 'success' },\n )\n props.onSaved(answer.sequence)\n } catch (error) {\n if (error instanceof OutreachRouteError && error.issues.length) {\n setServerIssues(\n error.issues.filter(\n (issue): issue is OutreachSequenceIssue => 'path' in issue,\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 const siteName = hosts.find((host) => host.id === draft.hostId)?.name ?? ''\n const countryOptions = [\n ...new Set([...orgCountries, ...draft.settings.allowedCountries]),\n ]\n\n return (\n <Grid container spacing={2}>\n <Grid size={{ xs: 12, md: 7 }}>\n <Stack spacing={2}>\n {archived ? (\n <Alert severity=\"info\">\n This sequence is archived, so it can’t be edited.\n </Alert>\n ) : null}\n <CardDisplay\n header=\"Sequence\"\n help={pluginDocsHelp('sequences', { anchor: '#build-a-sequence' })}\n contentGutterX\n contentGutterY\n >\n <Stack spacing={2}>\n <TextField\n label=\"Name\"\n value={draft.name}\n onChange={(event) => update({ name: event.target.value })}\n disabled={archived}\n error={Boolean(issueAt('name'))}\n helperText={issueAt('name')}\n slotProps={{\n htmlInput: { maxLength: OUTREACH_SEQUENCE_NAME_MAX + 20 },\n }}\n fullWidth\n />\n <TextField\n select\n label=\"Site\"\n value={\n hosts.some((host) => host.id === draft.hostId)\n ? draft.hostId\n : ''\n }\n onChange={(event) => update({ hostId: event.target.value })}\n disabled={archived || !hosts.length}\n error={Boolean(issueAt('hostId'))}\n helperText={\n issueAt('hostId') ??\n 'The site whose contacts this sequence emails.'\n }\n fullWidth\n >\n {hosts.map((host) => (\n <MenuItem key={host.id} value={host.id}>\n {host.name}\n </MenuItem>\n ))}\n </TextField>\n <OutreachSequenceMailboxPicker\n orgId={orgId}\n uid={uid}\n mailboxes={props.mailboxes}\n mailboxesPath={props.mailboxesPath}\n value={draft.mailboxId}\n onChange={(mailboxId) => update({ mailboxId })}\n error={issueAt('mailboxId')}\n disabled={archived}\n />\n </Stack>\n </CardDisplay>\n\n {listIssue ? <Alert severity=\"error\">{listIssue}</Alert> : null}\n {draft.steps.map((step, index) => (\n <OutreachStepCard\n key={step.id || `step-${index}`}\n step={step}\n index={index}\n count={draft.steps.length}\n firstEmail={\n draft.steps.findIndex((entry) => entry.kind === 'email') ===\n index\n }\n inThread={isInThreadEmailStep(draft.steps, index)}\n threadSubject={threadSubject(index)}\n templates={templates.data}\n issues={stepIssues(index)}\n disabled={archived}\n onChange={(next) => setStep(index, next)}\n onMove={(direction) => moveStep(index, direction)}\n onRemove={() =>\n update({\n steps: draft.steps.filter(\n (_entry, position) => position !== index,\n ),\n })\n }\n />\n ))}\n <Stack\n direction=\"row\"\n spacing={1}\n sx={{ flexWrap: 'wrap', rowGap: 1 }}\n >\n <Button\n variant=\"outlined\"\n startIcon={<MdiIcon path={mdiPlus.path} fontSize=\"small\" />}\n disabled={\n archived || full || emailCount >= OUTREACH_MAX_EMAIL_STEPS\n }\n onClick={() =>\n update({\n steps: [...draft.steps, newOutreachEmailStep(draft.steps)],\n })\n }\n >\n Add email\n </Button>\n <Button\n variant=\"outlined\"\n startIcon={<MdiIcon path={mdiPlus.path} fontSize=\"small\" />}\n disabled={archived || full}\n onClick={(event) => setTaskAnchor(event.currentTarget)}\n aria-haspopup=\"menu\"\n >\n Add task\n </Button>\n <Menu\n anchorEl={taskAnchor}\n open={Boolean(taskAnchor)}\n onClose={() => setTaskAnchor(null)}\n >\n {OUTREACH_TASK_KINDS.map((kind: OutreachTaskKind) => (\n <MenuItem\n key={kind}\n onClick={() => {\n setTaskAnchor(null)\n update({\n steps: [\n ...draft.steps,\n newOutreachTaskStep(draft.steps, kind),\n ],\n })\n }}\n >\n {OUTREACH_TASK_KIND_LABELS[kind]}\n </MenuItem>\n ))}\n </Menu>\n </Stack>\n <Typography variant=\"caption\" color=\"text.secondary\">\n {`Up to ${OUTREACH_MAX_STEPS} steps, ${OUTREACH_MAX_EMAIL_STEPS} of them emails.`}\n </Typography>\n\n <CardDisplay\n header=\"Who it sends to, and when\"\n help={pluginDocsHelp('sequences', {\n anchor: '#build-a-sequence',\n excerpt:\n 'A sequence sends only to the countries both it and your organization allow, and in its mailbox’s sending hours unless it has its own.',\n })}\n contentGutterX\n contentGutterY\n >\n <Stack spacing={2}>\n <Autocomplete<string, true>\n multiple\n options={countryOptions}\n value={draft.settings.allowedCountries}\n getOptionLabel={outreachCountryLabel}\n onChange={(_event, next) =>\n update({\n settings: { ...draft.settings, allowedCountries: next },\n })\n }\n disabled={archived}\n renderValue={(value, getItemProps) =>\n value.map((code, index) => {\n const { key, ...item } = getItemProps({ index })\n return (\n <Chip\n key={key}\n size=\"small\"\n label={outreachCountryLabel(code)}\n {...item}\n />\n )\n })\n }\n renderInput={(params) => (\n <TextField\n {...params}\n label=\"Countries\"\n error={Boolean(countriesIssue)}\n helperText={\n countriesIssue ??\n 'Among the countries your organization allows. Cold contacts are emailed only in the United States.'\n }\n />\n )}\n />\n <FormControlLabel\n control={\n <Switch\n checked={draft.settings.allowCustomers}\n onChange={(event) =>\n update({\n settings: {\n ...draft.settings,\n allowCustomers: event.target.checked,\n },\n })\n }\n disabled={archived}\n />\n }\n label=\"Include customers\"\n />\n <OutreachSendWindowFields\n window={draft.settings.window}\n onChange={(window) =>\n update({ settings: { ...draft.settings, window } })\n }\n daysIssue={issueAt('settings.window.days')}\n hoursIssue={issueAt('settings.window')}\n disabled={archived}\n />\n </Stack>\n </CardDisplay>\n\n {archived ? null : (\n <Stack\n direction={{ xs: 'column', sm: 'row' }}\n spacing={1}\n sx={{ justifyContent: 'flex-end' }}\n >\n {props.onCancel ? (\n <Button\n variant=\"text\"\n onClick={props.onCancel}\n disabled={saving}\n >\n Cancel\n </Button>\n ) : null}\n <Button\n variant=\"contained\"\n onClick={() => void save()}\n disabled={saving}\n >\n {saving ? 'Saving…' : sequence ? 'Save' : 'Create sequence'}\n </Button>\n </Stack>\n )}\n </Stack>\n </Grid>\n <Grid size={{ xs: 12, md: 5 }}>\n <Box sx={{ position: { md: 'sticky' }, top: { md: 16 } }}>\n <OutreachSequencePreview\n steps={draft.steps}\n orgSettings={settings.settings}\n orgSettingsStatus={settings.status}\n templates={templates.data}\n sender={\n mailbox\n ? {\n name: mailbox.displayName,\n email: mailbox.sendAs || mailbox.email,\n }\n : null\n }\n siteName={siteName}\n />\n </Box>\n </Grid>\n </Grid>\n )\n}\nOutreachSequenceEditor.displayName = 'OutreachSequenceEditor'\n\nexport default OutreachSequenceEditor\n"],"names":["pluginDocsHelp","mdiPlus","CardDisplay","MdiIcon","useSnackbar","useUser","Alert","Autocomplete","Box","Button","Chip","FormControlLabel","Grid","Menu","MenuItem","Stack","Switch","TextField","Typography","useEffect","useMemo","useState","isInThreadEmailStep","OUTREACH_SEQUENCE_NAME_MAX","validateOutreachSequence","outreachCountryLabel","OUTREACH_MAX_EMAIL_STEPS","OUTREACH_MAX_STEPS","OUTREACH_TASK_KIND_LABELS","OUTREACH_TASK_KINDS","emptyOutreachSequenceDraft","newOutreachEmailStep","newOutreachTaskStep","outreachSequenceDraftOf","OutreachSendWindowFields","OutreachSequenceMailboxPicker","OutreachSequencePreview","OutreachStepCard","OutreachRouteError","useOutreachApi","useOutreachEmailTemplates","stepIssueKey","path","match","exec","field","index","Number","OutreachSequenceEditor","props","issueAt","settings","issues","hosts","orgId","orgMount","sequence","api","enqueueSnackbar","data","user","uid","mountedHosts","orgCountries","allowedCountries","draft","setDraft","hostId","length","id","attempted","setAttempted","serverIssues","setServerIssues","saving","setSaving","taskAnchor","setTaskAnchor","settingsCountries","join","previous","split","ownSending","mailboxes","filter","entry","connectedByUid","status","onlyOwnMailbox","mailboxId","templates","mailbox","find","archived","judged","issue","severity","includes","message","stepIssues","found","key","listIssue","countriesIssue","startsWith","update","next","setStep","step","steps","map","position","moveStep","direction","moved","splice","emailCount","kind","full","threadSubject","subject","save","some","answer","saveSequence","created","variant","onSaved","error","allowDuplicate","siteName","host","name","countryOptions","Set","container","spacing","size","xs","md","header","help","anchor","contentGutterX","contentGutterY","label","value","onChange","event","target","disabled","Boolean","helperText","slotProps","htmlInput","maxLength","fullWidth","select","mailboxesPath","count","firstEmail","findIndex","inThread","onMove","onRemove","_entry","sx","flexWrap","rowGap","startIcon","fontSize","onClick","currentTarget","aria-haspopup","anchorEl","open","onClose","color","excerpt","multiple","options","getOptionLabel","_event","renderValue","getItemProps","code","item","renderInput","params","control","checked","allowCustomers","window","daysIssue","hoursIssue","sm","justifyContent","onCancel","top","orgSettings","orgSettingsStatus","sender","displayName","email","sendAs"],"mappings":"AAAA;;;;;;;;;;;;;;;CAeC,GACD;;;;AAEA,SAASA,cAAc,QAAoC,eAAc;AACzE,SAASC,OAAO,QAAQ,yBAAwB;AAChD,SAASC,WAAW,EAAEC,OAAO,QAAQ,uBAAsB;AAC3D,SAASC,WAAW,QAAQ,8BAA6B;AACzD,SAASC,OAAO,QAAQ,iCAAgC;AACxD,SACEC,KAAK,EACLC,YAAY,EACZC,GAAG,EACHC,MAAM,EACNC,IAAI,EACJC,gBAAgB,EAChBC,IAAI,EACJC,IAAI,EACJC,QAAQ,EACRC,KAAK,EACLC,MAAM,EACNC,SAAS,EACTC,UAAU,QACL,gBAAe;AACtB,SAASC,SAAS,EAAEC,OAAO,EAAEC,QAAQ,QAAQ,QAAO;AACpD,SACEC,mBAAmB,EACnBC,0BAA0B,EAC1BC,wBAAwB,QACnB,mCAA+B;AACtC,SAASC,oBAAoB,QAAQ,kCAA8B;AACnE,SACEC,wBAAwB,EACxBC,kBAAkB,EAClBC,yBAAyB,EACzBC,mBAAmB,QAId,6BAAyB;AAChC,SACEC,0BAA0B,EAC1BC,oBAAoB,EACpBC,mBAAmB,EACnBC,uBAAuB,QAGlB,6BAAyB;AAChC,SAASC,wBAAwB,QAAQ,0BAAsB;AAC/D,SAASC,6BAA6B,QAAQ,+BAA2B;AACzE,SAASC,uBAAuB,QAAQ,wBAAoB;AAC5D,SAASC,gBAAgB,QAAQ,0BAAsB;AACvD,SAASC,kBAAkB,EAAEC,cAAc,QAAQ,wBAAoB;AACvE,SAASC,yBAAyB,QAAQ,wBAAoB;AAsB9D,oEAAoE,GACpE,SAASC,aAAaC,IAAY;QAGlBC;IAFd,MAAMA,QAAQ,4BAA4BC,IAAI,CAACF;IAC/C,IAAI,CAACC,OAAO,OAAO;IACnB,MAAME,SAAQF,UAAAA,KAAK,CAAC,EAAE,YAARA,UAAY;IAC1B,OAAO;QAAEG,OAAOC,OAAOJ,KAAK,CAAC,EAAE;QAAGE,OAAOA,UAAU,OAAO,SAASA;IAAM;AAC3E;AAEA;;;;;;;;;;CAUC,GACD,OAAO,SAASG,uBAAuBC,KAAkC;qBA2DrEA,wCA2IcC;QA9LKC,oBAqBKA,qBA0DHC,cAkENC;IAxJjB,MAAM,EAAEC,KAAK,EAAEC,QAAQ,EAAEC,QAAQ,EAAEL,QAAQ,EAAE,GAAGF;IAChD,MAAMQ,MAAMlB,eAAee;IAC3B,MAAM,EAAEI,eAAe,EAAE,GAAGtD;IAC5B,MAAM,EAAEuD,MAAMC,IAAI,EAAE,GAAGvD;IACvB,MAAMwD,cAAMD,wBAAAA,KAAMC,GAAG,mBAAI;IACzB,MAAMC,eAAeP,4BAAAA,SAAUF,KAAK;IACpC,MAAMA,QAAQjC,QAAQ,IAAM0C,uBAAAA,eAAgB,EAAE,EAAE;QAACA;KAAa;IAC9D,MAAMC,yBAAeZ,qBAAAA,SAASA,QAAQ,qBAAjBA,mBAAmBa,gBAAgB,oBAAI;QAAC;KAAK;IAElE,MAAM,CAACC,OAAOC,SAAS,GAAG7C,SAAgC,IACxDmC,WACIvB,wBAAwBuB,YACxB1B,2BAA2B;YACzBqC,QAAQd,MAAMe,MAAM,KAAK,IAAIf,KAAK,CAAC,EAAE,CAACgB,EAAE,GAAG;YAC3CL,kBAAkBD;QACpB;IAEN,MAAM,CAACO,WAAWC,aAAa,GAAGlD,SAAS;IAC3C,MAAM,CAACmD,cAAcC,gBAAgB,GAAGpD,SAAkC,EAAE;IAC5E,MAAM,CAACqD,QAAQC,UAAU,GAAGtD,SAAS;IACrC,MAAM,CAACuD,YAAYC,cAAc,GAAGxD,SAA6B;IAEjE,0EAA0E;IAC1E,sBAAsB;IACtBF,UAAU;QACR,IAAIqC,UAAUU,SAASjC,wBAAwBuB;IACjD,GAAG;QAACA;KAAS;IACb,4EAA4E;IAC5E,MAAMsB,qBAAoB3B,sBAAAA,SAASA,QAAQ,qBAAjBA,oBAAmBa,gBAAgB,CAACe,IAAI,CAAC;IACnE5D,UAAU;QACR,IAAI,CAACqC,YAAYsB,mBAAmB;YAClCZ,SAAS,CAACc,WAAc,aACnBA;oBACH7B,UAAU,aACL6B,SAAS7B,QAAQ;wBACpBa,kBAAkBc,kBAAkBG,KAAK,CAAC;;;QAGhD;IACF,GAAG;QAACzB;QAAUsB;KAAkB;IAChC3D,UAAU;QACR,IAAI,CAACqC,YAAY,CAACS,MAAME,MAAM,IAAId,MAAMe,MAAM,KAAK,GACjDF,SAAS,CAACc,WAAc,aAAKA;gBAAUb,QAAQd,KAAK,CAAC,EAAE,CAACgB,EAAE;;IAC9D,GAAG;QAACb;QAAUS,MAAME,MAAM;QAAEd;KAAM;IAElC,2EAA2E;IAC3E,uBAAuB;IACvB,MAAM6B,aAAajC,MAAMkC,SAAS,CAACA,SAAS,CAACC,MAAM,CACjD,CAACC,QAAUA,MAAMC,cAAc,KAAKzB,OAAOwB,MAAME,MAAM,KAAK;IAE9D,MAAMC,iBAAiBN,WAAWd,MAAM,KAAK,IAAIc,UAAU,CAAC,EAAE,CAACb,EAAE,GAAG;IACpElD,UAAU;QACR,IAAI,CAACqC,YAAY,CAACS,MAAMwB,SAAS,IAAID,gBACnCtB,SAAS,CAACc,WAAc,aAAKA;gBAAUS,WAAWD;;IACtD,GAAG;QAAChC;QAAUS,MAAMwB,SAAS;QAAED;KAAe;IAE9C,MAAME,YAAYlD,0BAA0Bc,OAAOW,MAAME,MAAM,IAAI,MAAMN;IACzE,MAAM8B,WACJ1C,kCAAAA,MAAMkC,SAAS,CAACA,SAAS,CAACS,IAAI,CAAC,CAACP,QAAUA,MAAMhB,EAAE,KAAKJ,MAAMwB,SAAS,aAAtExC,kCACA;IACF,MAAM4C,WAAWrC,CAAAA,4BAAAA,SAAU+B,MAAM,MAAK;IAEtC,MAAMnC,SAAShC,QAAQ;QACrB,MAAM0E,SAAS;eACVtE,yBAAyByC;eACzBO;SACJ;QACD,OAAOsB,OAAOV,MAAM,CAClB,CAACW,QACCA,MAAMC,QAAQ,KAAK,aACnB1B,aACAE,aAAayB,QAAQ,CAACF;IAE5B,GAAG;QAAC9B;QAAOO;QAAcF;KAAU;IACnC,MAAMpB,UAAU,CAACR;YACfU;gBAAAA,eAAAA,OAAOwC,IAAI,CAAC,CAACG,QAAUA,MAAMrD,IAAI,KAAKA,0BAAtCU,aAA6C8C,OAAO;;IACtD,MAAMC,aAAa,CAACrD;QAClB,MAAMsD,QAAgC,CAAC;QACvC,KAAK,MAAML,SAAS3C,OAAQ;YAC1B,MAAMiD,MAAM5D,aAAasD,MAAMrD,IAAI;YACnC,IAAI2D,CAAAA,uBAAAA,IAAKvD,KAAK,MAAKA,SAAS,CAACsD,KAAK,CAACC,IAAIxD,KAAK,CAAC,EAC3CuD,KAAK,CAACC,IAAIxD,KAAK,CAAC,GAAGkD,MAAMG,OAAO;QACpC;QACA,OAAOE;IACT;IACA,MAAME,YAAYpD,QAAQ;IAC1B,MAAMqD,kBAAiBnD,eAAAA,OAAOwC,IAAI,CAAC,CAACG,QAClCA,MAAMrD,IAAI,CAAC8D,UAAU,CAAC,kDADDpD,aAEpB8C,OAAO;IAEV,MAAMO,SAAS,CAACC;QACdjC,gBAAgB,EAAE;QAClBP,SAAS,CAACc,WAAc,aAAKA,UAAa0B;IAC5C;IACA,MAAMC,UAAU,CAAC7D,OAAe8D,OAC9BH,OAAO;YACLI,OAAO5C,MAAM4C,KAAK,CAACC,GAAG,CAAC,CAACzB,OAAO0B,WAC7BA,aAAajE,QAAQ8D,OAAOvB;QAEhC;IACF,MAAM2B,WAAW,CAAClE,OAAemE;QAC/B,MAAMJ,QAAQ;eAAI5C,MAAM4C,KAAK;SAAC;QAC9B,MAAM,CAACK,MAAM,GAAGL,MAAMM,MAAM,CAACrE,OAAO;QACpC+D,MAAMM,MAAM,CAACrE,QAAQmE,WAAW,GAAGC;QACnCT,OAAO;YAAEI;QAAM;IACjB;IACA,MAAMO,aAAanD,MAAM4C,KAAK,CAACzB,MAAM,CAAC,CAACwB,OAASA,KAAKS,IAAI,KAAK,SAASjD,MAAM;IAC7E,MAAMkD,OAAOrD,MAAM4C,KAAK,CAACzC,MAAM,IAAIzC;IACnC,MAAM4F,gBAAgB,CAACzE;QACrB,IAAK,IAAIiE,WAAWjE,QAAQ,GAAGiE,YAAY,GAAGA,YAAY,EAAG;YAC3D,MAAMH,OAAO3C,MAAM4C,KAAK,CAACE,SAAS;YAClC,IAAIH,KAAKS,IAAI,KAAK,WAAW,CAAC/F,oBAAoB2C,MAAM4C,KAAK,EAAEE,WAC7D,OAAOH,KAAKY,OAAO;QACvB;QACA,OAAO;IACT;IAEA,MAAMC,OAAO;QACXlD,aAAa;QACb,IACE/C,yBAAyByC,OAAOyD,IAAI,CAClC,CAAC3B,QAAUA,MAAMC,QAAQ,KAAK,UAGhC;QACFrB,UAAU;QACV,IAAI;;YACF,MAAMgD,SAAS,MAAMlE,IAAImE,YAAY,SAACpE,4BAAAA,SAAUa,EAAE,mBAAI,MAAMJ;YAC5DQ,gBAAgB,EAAE;YAClBF,aAAa;YACbb,gBACEiE,OAAOE,OAAO,GAAG,sBAAsB,mBACvC;gBAAEC,SAAS;YAAU;YAEvB7E,MAAM8E,OAAO,CAACJ,OAAOnE,QAAQ;QAC/B,EAAE,OAAOwE,OAAO;YACd,IAAIA,iBAAiB1F,sBAAsB0F,MAAM5E,MAAM,CAACgB,MAAM,EAAE;gBAC9DK,gBACEuD,MAAM5E,MAAM,CAACgC,MAAM,CACjB,CAACW,QAA0C,UAAUA;YAG3D;YACArC,gBAAgB,AAACsE,MAAgB9B,OAAO,EAAE;gBACxC4B,SAAS;gBACTG,gBAAgB;YAClB;QACF,SAAU;YACRtD,UAAU;QACZ;IACF;IAEA,MAAMuD,qBAAW7E,cAAAA,MAAMuC,IAAI,CAAC,CAACuC,OAASA,KAAK9D,EAAE,KAAKJ,MAAME,MAAM,sBAA7Cd,YAAgD+E,IAAI,oBAAI;IACzE,MAAMC,iBAAiB;WAClB,IAAIC,IAAI;eAAIvE;eAAiBE,MAAMd,QAAQ,CAACa,gBAAgB;SAAC;KACjE;IAED,qBACE,MAACpD;QAAK2H,SAAS;QAACC,SAAS;;0BACvB,KAAC5H;gBAAK6H,MAAM;oBAAEC,IAAI;oBAAIC,IAAI;gBAAE;0BAC1B,cAAA,MAAC5H;oBAAMyH,SAAS;;wBACb3C,yBACC,KAACvF;4BAAM0F,UAAS;sCAAO;6BAGrB;sCACJ,KAAC9F;4BACC0I,QAAO;4BACPC,MAAM7I,eAAe,aAAa;gCAAE8I,QAAQ;4BAAoB;4BAChEC,cAAc;4BACdC,cAAc;sCAEd,cAAA,MAACjI;gCAAMyH,SAAS;;kDACd,KAACvH;wCACCgI,OAAM;wCACNC,OAAOjF,MAAMmE,IAAI;wCACjBe,UAAU,CAACC,QAAU3C,OAAO;gDAAE2B,MAAMgB,MAAMC,MAAM,CAACH,KAAK;4CAAC;wCACvDI,UAAUzD;wCACVmC,OAAOuB,QAAQrG,QAAQ;wCACvBsG,YAAYtG,QAAQ;wCACpBuG,WAAW;4CACTC,WAAW;gDAAEC,WAAWpI,6BAA6B;4CAAG;wCAC1D;wCACAqI,SAAS;;kDAEX,KAAC3I;wCACC4I,MAAM;wCACNZ,OAAM;wCACNC,OACE7F,MAAMqE,IAAI,CAAC,CAACS,OAASA,KAAK9D,EAAE,KAAKJ,MAAME,MAAM,IACzCF,MAAME,MAAM,GACZ;wCAENgF,UAAU,CAACC,QAAU3C,OAAO;gDAAEtC,QAAQiF,MAAMC,MAAM,CAACH,KAAK;4CAAC;wCACzDI,UAAUzD,YAAY,CAACxC,MAAMe,MAAM;wCACnC4D,OAAOuB,QAAQrG,QAAQ;wCACvBsG,UAAU,GACRtG,WAAAA,QAAQ,qBAARA,WACA;wCAEF0G,SAAS;kDAERvG,MAAMyD,GAAG,CAAC,CAACqB,qBACV,KAACrH;gDAAuBoI,OAAOf,KAAK9D,EAAE;0DACnC8D,KAAKC,IAAI;+CADGD,KAAK9D,EAAE;;kDAK1B,KAAClC;wCACCmB,OAAOA;wCACPO,KAAKA;wCACLsB,WAAWlC,MAAMkC,SAAS;wCAC1B2E,eAAe7G,MAAM6G,aAAa;wCAClCZ,OAAOjF,MAAMwB,SAAS;wCACtB0D,UAAU,CAAC1D,YAAcgB,OAAO;gDAAEhB;4CAAU;wCAC5CuC,OAAO9E,QAAQ;wCACfoG,UAAUzD;;;;;wBAKfS,0BAAY,KAAChG;4BAAM0F,UAAS;sCAASM;6BAAqB;wBAC1DrC,MAAM4C,KAAK,CAACC,GAAG,CAAC,CAACF,MAAM9D,sBACtB,KAACT;gCAECuE,MAAMA;gCACN9D,OAAOA;gCACPiH,OAAO9F,MAAM4C,KAAK,CAACzC,MAAM;gCACzB4F,YACE/F,MAAM4C,KAAK,CAACoD,SAAS,CAAC,CAAC5E,QAAUA,MAAMgC,IAAI,KAAK,aAChDvE;gCAEFoH,UAAU5I,oBAAoB2C,MAAM4C,KAAK,EAAE/D;gCAC3CyE,eAAeA,cAAczE;gCAC7B4C,WAAWA,UAAU/B,IAAI;gCACzBP,QAAQ+C,WAAWrD;gCACnBwG,UAAUzD;gCACVsD,UAAU,CAACzC,OAASC,QAAQ7D,OAAO4D;gCACnCyD,QAAQ,CAAClD,YAAcD,SAASlE,OAAOmE;gCACvCmD,UAAU,IACR3D,OAAO;wCACLI,OAAO5C,MAAM4C,KAAK,CAACzB,MAAM,CACvB,CAACiF,QAAQtD,WAAaA,aAAajE;oCAEvC;+BApBG8D,KAAKvC,EAAE,IAAI,CAAC,KAAK,EAAEvB,OAAO;sCAwBnC,MAAC/B;4BACCkG,WAAU;4BACVuB,SAAS;4BACT8B,IAAI;gCAAEC,UAAU;gCAAQC,QAAQ;4BAAE;;8CAElC,KAAC/J;oCACCqH,SAAQ;oCACR2C,yBAAW,KAACtK;wCAAQuC,MAAMzC,QAAQyC,IAAI;wCAAEgI,UAAS;;oCACjDpB,UACEzD,YAAYyB,QAAQF,cAAc1F;oCAEpCiJ,SAAS,IACPlE,OAAO;4CACLI,OAAO;mDAAI5C,MAAM4C,KAAK;gDAAE9E,qBAAqBkC,MAAM4C,KAAK;6CAAE;wCAC5D;8CAEH;;8CAGD,KAACpG;oCACCqH,SAAQ;oCACR2C,yBAAW,KAACtK;wCAAQuC,MAAMzC,QAAQyC,IAAI;wCAAEgI,UAAS;;oCACjDpB,UAAUzD,YAAYyB;oCACtBqD,SAAS,CAACvB,QAAUvE,cAAcuE,MAAMwB,aAAa;oCACrDC,iBAAc;8CACf;;8CAGD,KAAChK;oCACCiK,UAAUlG;oCACVmG,MAAMxB,QAAQ3E;oCACdoG,SAAS,IAAMnG,cAAc;8CAE5BhD,oBAAoBiF,GAAG,CAAC,CAACO,qBACxB,KAACvG;4CAEC6J,SAAS;gDACP9F,cAAc;gDACd4B,OAAO;oDACLI,OAAO;2DACF5C,MAAM4C,KAAK;wDACd7E,oBAAoBiC,MAAM4C,KAAK,EAAEQ;qDAClC;gDACH;4CACF;sDAECzF,yBAAyB,CAACyF,KAAK;2CAX3BA;;;;sCAgBb,KAACnG;4BAAW4G,SAAQ;4BAAUmD,OAAM;sCACjC,CAAC,MAAM,EAAEtJ,mBAAmB,QAAQ,EAAED,yBAAyB,gBAAgB,CAAC;;sCAGnF,KAACxB;4BACC0I,QAAO;4BACPC,MAAM7I,eAAe,aAAa;gCAChC8I,QAAQ;gCACRoC,SACE;4BACJ;4BACAnC,cAAc;4BACdC,cAAc;sCAEd,cAAA,MAACjI;gCAAMyH,SAAS;;kDACd,KAACjI;wCACC4K,QAAQ;wCACRC,SAAS/C;wCACTa,OAAOjF,MAAMd,QAAQ,CAACa,gBAAgB;wCACtCqH,gBAAgB5J;wCAChB0H,UAAU,CAACmC,QAAQ5E,OACjBD,OAAO;gDACLtD,UAAU,aAAKc,MAAMd,QAAQ;oDAAEa,kBAAkB0C;;4CACnD;wCAEF4C,UAAUzD;wCACV0F,aAAa,CAACrC,OAAOsC,eACnBtC,MAAMpC,GAAG,CAAC,CAAC2E,MAAM3I;gDACf,MAAyB0I,gBAAAA,aAAa;oDAAE1I;gDAAM,IAAxC,EAAEuD,GAAG,EAAW,GAAGmF,eAATE,wCAASF;;;gDACzB,qBACE,KAAC9K;oDAEC+H,MAAK;oDACLQ,OAAOxH,qBAAqBgK;mDACxBC,OAHCrF;4CAMX;wCAEFsF,aAAa,CAACC,uBACZ,KAAC3K,wBACK2K;gDACJ3C,OAAM;gDACNjB,OAAOuB,QAAQhD;gDACfiD,UAAU,EACRjD,yBAAAA,iBACA;;;kDAKR,KAAC5F;wCACCkL,uBACE,KAAC7K;4CACC8K,SAAS7H,MAAMd,QAAQ,CAAC4I,cAAc;4CACtC5C,UAAU,CAACC,QACT3C,OAAO;oDACLtD,UAAU,aACLc,MAAMd,QAAQ;wDACjB4I,gBAAgB3C,MAAMC,MAAM,CAACyC,OAAO;;gDAExC;4CAEFxC,UAAUzD;;wCAGdoD,OAAM;;kDAER,KAAC/G;wCACC8J,QAAQ/H,MAAMd,QAAQ,CAAC6I,MAAM;wCAC7B7C,UAAU,CAAC6C,SACTvF,OAAO;gDAAEtD,UAAU,aAAKc,MAAMd,QAAQ;oDAAE6I;;4CAAS;wCAEnDC,WAAW/I,QAAQ;wCACnBgJ,YAAYhJ,QAAQ;wCACpBoG,UAAUzD;;;;;wBAKfA,WAAW,qBACV,MAAC9E;4BACCkG,WAAW;gCAAEyB,IAAI;gCAAUyD,IAAI;4BAAM;4BACrC3D,SAAS;4BACT8B,IAAI;gCAAE8B,gBAAgB;4BAAW;;gCAEhCnJ,MAAMoJ,QAAQ,iBACb,KAAC5L;oCACCqH,SAAQ;oCACR6C,SAAS1H,MAAMoJ,QAAQ;oCACvB/C,UAAU5E;8CACX;qCAGC;8CACJ,KAACjE;oCACCqH,SAAQ;oCACR6C,SAAS,IAAM,KAAKlD;oCACpB6B,UAAU5E;8CAETA,SAAS,YAAYlB,WAAW,SAAS;;;;;;;0BAMpD,KAAC5C;gBAAK6H,MAAM;oBAAEC,IAAI;oBAAIC,IAAI;gBAAE;0BAC1B,cAAA,KAACnI;oBAAI8J,IAAI;wBAAEvD,UAAU;4BAAE4B,IAAI;wBAAS;wBAAG2D,KAAK;4BAAE3D,IAAI;wBAAG;oBAAE;8BACrD,cAAA,KAACvG;wBACCyE,OAAO5C,MAAM4C,KAAK;wBAClB0F,aAAapJ,SAASA,QAAQ;wBAC9BqJ,mBAAmBrJ,SAASoC,MAAM;wBAClCG,WAAWA,UAAU/B,IAAI;wBACzB8I,QACE9G,UACI;4BACEyC,MAAMzC,QAAQ+G,WAAW;4BACzBC,OAAOhH,QAAQiH,MAAM,IAAIjH,QAAQgH,KAAK;wBACxC,IACA;wBAENzE,UAAUA;;;;;;AAMtB;AACAlF,uBAAuB0J,WAAW,GAAG;AAErC,eAAe1J,uBAAsB"}
@@ -0,0 +1,44 @@
1
+ import type { OutreachMailbox } from '../model/outreach.types';
2
+ import type { OutreachMailboxesResult } from './use-outreach-mailboxes';
3
+ export interface OutreachSequenceMailboxPickerProps {
4
+ orgId: string;
5
+ /** The member choosing, whose own mailboxes are offered. */
6
+ uid: string | null;
7
+ /** The organization's mailboxes, from the Mailboxes section's own listener. */
8
+ mailboxes: OutreachMailboxesResult;
9
+ /** The Mailboxes section, where a mailbox is connected, resumed or reconnected. */
10
+ mailboxesPath: string;
11
+ value: string;
12
+ onChange(mailboxId: string): void;
13
+ error?: string;
14
+ disabled?: boolean;
15
+ }
16
+ /** A mailbox as its line in the menu reads: who mail is from, and any status that stops it sending. */
17
+ export declare function outreachMailboxOptionLabel(mailbox: OutreachMailbox): string;
18
+ /**
19
+ * The mailboxes a member may choose for a sequence: their own, or every
20
+ * one for an organization owner or admin — the two the save route lets
21
+ * send from a mailbox — never a disconnected one. The mailbox a sequence
22
+ * already names stays in the list whoever connected it, so the field never
23
+ * reads as empty.
24
+ */
25
+ export declare function outreachOfferedMailboxes(mailboxes: readonly OutreachMailbox[], input: {
26
+ uid: string | null;
27
+ canManageAll: boolean;
28
+ value: string;
29
+ }): OutreachMailbox[];
30
+ /**
31
+ * The mailbox a sequence sends from (AGL-2980), chosen from the Mailboxes
32
+ * section's own listener and route (AGL-2978).
33
+ *
34
+ * Whether the member may choose a colleague's mailbox is the mailbox
35
+ * routes' answer (`availability().canManageAll`); until it arrives, or when
36
+ * it cannot be had, the member is offered their own, which is always
37
+ * allowed. A chosen mailbox that is paused or waiting to be reconnected can
38
+ * hold a draft, and the field says what activating will need.
39
+ */
40
+ export declare function OutreachSequenceMailboxPicker(props: OutreachSequenceMailboxPickerProps): import("react").JSX.Element;
41
+ export declare namespace OutreachSequenceMailboxPicker {
42
+ var displayName: string;
43
+ }
44
+ export default OutreachSequenceMailboxPicker;