@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.
- package/LICENSE +201 -0
- package/README.md +93 -0
- package/package.json +52 -0
- package/src/index.d.ts +22 -0
- package/src/index.js +29 -0
- package/src/index.js.map +1 -0
- package/src/lib/components/compliance-section.d.ts +20 -0
- package/src/lib/components/compliance-section.js +291 -0
- package/src/lib/components/compliance-section.js.map +1 -0
- package/src/lib/components/enroll-dialog.d.ts +36 -0
- package/src/lib/components/enroll-dialog.js +656 -0
- package/src/lib/components/enroll-dialog.js.map +1 -0
- package/src/lib/components/enrollments-table.d.ts +28 -0
- package/src/lib/components/enrollments-table.js +375 -0
- package/src/lib/components/enrollments-table.js.map +1 -0
- package/src/lib/components/mailbox-card.d.ts +46 -0
- package/src/lib/components/mailbox-card.js +517 -0
- package/src/lib/components/mailbox-card.js.map +1 -0
- package/src/lib/components/mailboxes-section.d.ts +24 -0
- package/src/lib/components/mailboxes-section.js +258 -0
- package/src/lib/components/mailboxes-section.js.map +1 -0
- package/src/lib/components/outreach-console-page.d.ts +17 -0
- package/src/lib/components/outreach-console-page.js +81 -0
- package/src/lib/components/outreach-console-page.js.map +1 -0
- package/src/lib/components/outreach-console-sections.d.ts +43 -0
- package/src/lib/components/outreach-console-sections.js +55 -0
- package/src/lib/components/outreach-console-sections.js.map +1 -0
- package/src/lib/components/outreach-ui.d.ts +51 -0
- package/src/lib/components/outreach-ui.js +171 -0
- package/src/lib/components/outreach-ui.js.map +1 -0
- package/src/lib/components/send-window-fields.d.ts +25 -0
- package/src/lib/components/send-window-fields.js +178 -0
- package/src/lib/components/send-window-fields.js.map +1 -0
- package/src/lib/components/sequence-detail.d.ts +54 -0
- package/src/lib/components/sequence-detail.js +435 -0
- package/src/lib/components/sequence-detail.js.map +1 -0
- package/src/lib/components/sequence-editor.d.ts +37 -0
- package/src/lib/components/sequence-editor.js +485 -0
- package/src/lib/components/sequence-editor.js.map +1 -0
- package/src/lib/components/sequence-mailbox-picker.d.ts +44 -0
- package/src/lib/components/sequence-mailbox-picker.js +137 -0
- package/src/lib/components/sequence-mailbox-picker.js.map +1 -0
- package/src/lib/components/sequence-preview.d.ts +27 -0
- package/src/lib/components/sequence-preview.js +146 -0
- package/src/lib/components/sequence-preview.js.map +1 -0
- package/src/lib/components/sequence-step-card.d.ts +31 -0
- package/src/lib/components/sequence-step-card.js +326 -0
- package/src/lib/components/sequence-step-card.js.map +1 -0
- package/src/lib/components/sequences-section.d.ts +40 -0
- package/src/lib/components/sequences-section.js +310 -0
- package/src/lib/components/sequences-section.js.map +1 -0
- package/src/lib/components/use-outreach-api.d.ts +38 -0
- package/src/lib/components/use-outreach-api.js +139 -0
- package/src/lib/components/use-outreach-api.js.map +1 -0
- package/src/lib/components/use-outreach-crm.d.ts +50 -0
- package/src/lib/components/use-outreach-crm.js +200 -0
- package/src/lib/components/use-outreach-crm.js.map +1 -0
- package/src/lib/components/use-outreach-data.d.ts +55 -0
- package/src/lib/components/use-outreach-data.js +199 -0
- package/src/lib/components/use-outreach-data.js.map +1 -0
- package/src/lib/components/use-outreach-mailbox-api.d.ts +30 -0
- package/src/lib/components/use-outreach-mailbox-api.js +101 -0
- package/src/lib/components/use-outreach-mailbox-api.js.map +1 -0
- package/src/lib/components/use-outreach-mailboxes.d.ts +22 -0
- package/src/lib/components/use-outreach-mailboxes.js +68 -0
- package/src/lib/components/use-outreach-mailboxes.js.map +1 -0
- package/src/lib/components/use-outreach-settings.d.ts +17 -0
- package/src/lib/components/use-outreach-settings.js +64 -0
- package/src/lib/components/use-outreach-settings.js.map +1 -0
- package/src/lib/constants/api-routes.d.ts +68 -0
- package/src/lib/constants/api-routes.js +57 -0
- package/src/lib/constants/api-routes.js.map +1 -0
- package/src/lib/constants/bundle-common.d.ts +46 -0
- package/src/lib/constants/bundle-common.js +55 -0
- package/src/lib/constants/bundle-common.js.map +1 -0
- package/src/lib/constants/runtime-jobs.d.ts +24 -0
- package/src/lib/constants/runtime-jobs.js +24 -0
- package/src/lib/constants/runtime-jobs.js.map +1 -0
- package/src/lib/declarations.console-server.d.ts +38 -0
- package/src/lib/declarations.console-server.js +99 -0
- package/src/lib/declarations.console-server.js.map +1 -0
- package/src/lib/engine/compose.d.ts +86 -0
- package/src/lib/engine/compose.js +212 -0
- package/src/lib/engine/compose.js.map +1 -0
- package/src/lib/engine/delivery-status.d.ts +53 -0
- package/src/lib/engine/delivery-status.js +184 -0
- package/src/lib/engine/delivery-status.js.map +1 -0
- package/src/lib/engine/do-not-contact.d.ts +18 -0
- package/src/lib/engine/do-not-contact.js +34 -0
- package/src/lib/engine/do-not-contact.js.map +1 -0
- package/src/lib/engine/enrollment-state.d.ts +156 -0
- package/src/lib/engine/enrollment-state.js +303 -0
- package/src/lib/engine/enrollment-state.js.map +1 -0
- package/src/lib/engine/gates.d.ts +125 -0
- package/src/lib/engine/gates.js +232 -0
- package/src/lib/engine/gates.js.map +1 -0
- package/src/lib/engine/index.d.ts +28 -0
- package/src/lib/engine/index.js +33 -0
- package/src/lib/engine/index.js.map +1 -0
- package/src/lib/engine/mailbox-health.d.ts +49 -0
- package/src/lib/engine/mailbox-health.js +83 -0
- package/src/lib/engine/mailbox-health.js.map +1 -0
- package/src/lib/engine/opt-out-intent.d.ts +41 -0
- package/src/lib/engine/opt-out-intent.js +220 -0
- package/src/lib/engine/opt-out-intent.js.map +1 -0
- package/src/lib/engine/recipient-country.d.ts +41 -0
- package/src/lib/engine/recipient-country.js +171 -0
- package/src/lib/engine/recipient-country.js.map +1 -0
- package/src/lib/engine/schedule.d.ts +70 -0
- package/src/lib/engine/schedule.js +115 -0
- package/src/lib/engine/schedule.js.map +1 -0
- package/src/lib/engine/sending-capacity.d.ts +96 -0
- package/src/lib/engine/sending-capacity.js +172 -0
- package/src/lib/engine/sending-capacity.js.map +1 -0
- package/src/lib/engine/sequence-validation.d.ts +90 -0
- package/src/lib/engine/sequence-validation.js +291 -0
- package/src/lib/engine/sequence-validation.js.map +1 -0
- package/src/lib/engine/thread-classification.d.ts +78 -0
- package/src/lib/engine/thread-classification.js +224 -0
- package/src/lib/engine/thread-classification.js.map +1 -0
- package/src/lib/engine/thread-message.d.ts +80 -0
- package/src/lib/engine/thread-message.js +143 -0
- package/src/lib/engine/thread-message.js.map +1 -0
- package/src/lib/enrollment/enroll-people.d.ts +81 -0
- package/src/lib/enrollment/enroll-people.js +250 -0
- package/src/lib/enrollment/enroll-people.js.map +1 -0
- package/src/lib/enrollment/gate-lookups.d.ts +32 -0
- package/src/lib/enrollment/gate-lookups.js +154 -0
- package/src/lib/enrollment/gate-lookups.js.map +1 -0
- package/src/lib/mailboxes/mailbox-api.d.ts +126 -0
- package/src/lib/mailboxes/mailbox-api.js +66 -0
- package/src/lib/mailboxes/mailbox-api.js.map +1 -0
- package/src/lib/mailboxes/mailbox-credentials.d.ts +95 -0
- package/src/lib/mailboxes/mailbox-credentials.js +102 -0
- package/src/lib/mailboxes/mailbox-credentials.js.map +1 -0
- package/src/lib/mailboxes/mailbox-erasure.d.ts +69 -0
- package/src/lib/mailboxes/mailbox-erasure.js +148 -0
- package/src/lib/mailboxes/mailbox-erasure.js.map +1 -0
- package/src/lib/mailboxes/mailbox-gate.d.ts +75 -0
- package/src/lib/mailboxes/mailbox-gate.js +98 -0
- package/src/lib/mailboxes/mailbox-gate.js.map +1 -0
- package/src/lib/mailboxes/mailbox-revoke.d.ts +59 -0
- package/src/lib/mailboxes/mailbox-revoke.js +41 -0
- package/src/lib/mailboxes/mailbox-revoke.js.map +1 -0
- package/src/lib/mailboxes/mailbox-routes.d.ts +119 -0
- package/src/lib/mailboxes/mailbox-routes.js +605 -0
- package/src/lib/mailboxes/mailbox-routes.js.map +1 -0
- package/src/lib/mailboxes/mailbox-settings.d.ts +110 -0
- package/src/lib/mailboxes/mailbox-settings.js +212 -0
- package/src/lib/mailboxes/mailbox-settings.js.map +1 -0
- package/src/lib/mailboxes/mailbox-transport.d.ts +64 -0
- package/src/lib/mailboxes/mailbox-transport.js +94 -0
- package/src/lib/mailboxes/mailbox-transport.js.map +1 -0
- package/src/lib/mailboxes/oauth-redirect.d.ts +41 -0
- package/src/lib/mailboxes/oauth-redirect.js +63 -0
- package/src/lib/mailboxes/oauth-redirect.js.map +1 -0
- package/src/lib/mailboxes/oauth-state.d.ts +152 -0
- package/src/lib/mailboxes/oauth-state.js +212 -0
- package/src/lib/mailboxes/oauth-state.js.map +1 -0
- package/src/lib/mailboxes/outreach-config.d.ts +64 -0
- package/src/lib/mailboxes/outreach-config.js +77 -0
- package/src/lib/mailboxes/outreach-config.js.map +1 -0
- package/src/lib/mailboxes/register-mailbox-routes.d.ts +47 -0
- package/src/lib/mailboxes/register-mailbox-routes.js +135 -0
- package/src/lib/mailboxes/register-mailbox-routes.js.map +1 -0
- package/src/lib/model/compliance-settings.d.ts +78 -0
- package/src/lib/model/compliance-settings.js +155 -0
- package/src/lib/model/compliance-settings.js.map +1 -0
- package/src/lib/model/outreach-api.d.ts +210 -0
- package/src/lib/model/outreach-api.js +28 -0
- package/src/lib/model/outreach-api.js.map +1 -0
- package/src/lib/model/outreach.types.d.ts +563 -0
- package/src/lib/model/outreach.types.js +225 -0
- package/src/lib/model/outreach.types.js.map +1 -0
- package/src/lib/model/sequence-draft.d.ts +84 -0
- package/src/lib/model/sequence-draft.js +239 -0
- package/src/lib/model/sequence-draft.js.map +1 -0
- package/src/lib/model/step-preview.d.ts +45 -0
- package/src/lib/model/step-preview.js +98 -0
- package/src/lib/model/step-preview.js.map +1 -0
- package/src/lib/model/stored-records.d.ts +23 -0
- package/src/lib/model/stored-records.js +84 -0
- package/src/lib/model/stored-records.js.map +1 -0
- package/src/lib/plugin.d.ts +46 -0
- package/src/lib/plugin.js +86 -0
- package/src/lib/plugin.js.map +1 -0
- package/src/lib/routes/enroll-routes.d.ts +64 -0
- package/src/lib/routes/enroll-routes.js +350 -0
- package/src/lib/routes/enroll-routes.js.map +1 -0
- package/src/lib/routes/enrollment-routes.d.ts +19 -0
- package/src/lib/routes/enrollment-routes.js +171 -0
- package/src/lib/routes/enrollment-routes.js.map +1 -0
- package/src/lib/routes/platform-deps.d.ts +51 -0
- package/src/lib/routes/platform-deps.js +66 -0
- package/src/lib/routes/platform-deps.js.map +1 -0
- package/src/lib/routes/preview-routes.d.ts +33 -0
- package/src/lib/routes/preview-routes.js +117 -0
- package/src/lib/routes/preview-routes.js.map +1 -0
- package/src/lib/routes/register-routes.d.ts +22 -0
- package/src/lib/routes/register-routes.js +92 -0
- package/src/lib/routes/register-routes.js.map +1 -0
- package/src/lib/routes/route-deps.d.ts +49 -0
- package/src/lib/routes/route-deps.js +27 -0
- package/src/lib/routes/route-deps.js.map +1 -0
- package/src/lib/routes/route-gate.d.ts +94 -0
- package/src/lib/routes/route-gate.js +87 -0
- package/src/lib/routes/route-gate.js.map +1 -0
- package/src/lib/routes/route-http.d.ts +32 -0
- package/src/lib/routes/route-http.js +62 -0
- package/src/lib/routes/route-http.js.map +1 -0
- package/src/lib/routes/sequence-routes.d.ts +32 -0
- package/src/lib/routes/sequence-routes.js +359 -0
- package/src/lib/routes/sequence-routes.js.map +1 -0
- package/src/lib/routes/settings-routes.d.ts +30 -0
- package/src/lib/routes/settings-routes.js +73 -0
- package/src/lib/routes/settings-routes.js.map +1 -0
- package/src/lib/runtime/enrollment-events.d.ts +86 -0
- package/src/lib/runtime/enrollment-events.js +141 -0
- package/src/lib/runtime/enrollment-events.js.map +1 -0
- package/src/lib/runtime/fixtures/fake-gmail.d.ts +121 -0
- package/src/lib/runtime/fixtures/fake-gmail.js +312 -0
- package/src/lib/runtime/fixtures/fake-gmail.js.map +1 -0
- package/src/lib/runtime/mailbox-health-store.d.ts +47 -0
- package/src/lib/runtime/mailbox-health-store.js +168 -0
- package/src/lib/runtime/mailbox-health-store.js.map +1 -0
- package/src/lib/runtime/person-erasure.d.ts +39 -0
- package/src/lib/runtime/person-erasure.js +57 -0
- package/src/lib/runtime/person-erasure.js.map +1 -0
- package/src/lib/runtime/platform-runtime-deps.d.ts +29 -0
- package/src/lib/runtime/platform-runtime-deps.js +98 -0
- package/src/lib/runtime/platform-runtime-deps.js.map +1 -0
- package/src/lib/runtime/runtime-deps.d.ts +77 -0
- package/src/lib/runtime/runtime-deps.js +18 -0
- package/src/lib/runtime/runtime-deps.js.map +1 -0
- package/src/lib/runtime/send-job.d.ts +42 -0
- package/src/lib/runtime/send-job.js +780 -0
- package/src/lib/runtime/send-job.js.map +1 -0
- package/src/lib/runtime/sync-job.d.ts +41 -0
- package/src/lib/runtime/sync-job.js +480 -0
- package/src/lib/runtime/sync-job.js.map +1 -0
- package/src/lib/runtime/timeline.d.ts +67 -0
- package/src/lib/runtime/timeline.js +93 -0
- package/src/lib/runtime/timeline.js.map +1 -0
- package/src/lib/runtime/unsubscribe-link.d.ts +75 -0
- package/src/lib/runtime/unsubscribe-link.js +121 -0
- package/src/lib/runtime/unsubscribe-link.js.map +1 -0
- package/src/lib/runtime/unsubscribe-route.d.ts +24 -0
- package/src/lib/runtime/unsubscribe-route.js +103 -0
- package/src/lib/runtime/unsubscribe-route.js.map +1 -0
- package/src/lib/server.d.ts +53 -0
- package/src/lib/server.js +94 -0
- package/src/lib/server.js.map +1 -0
- package/src/lib/storage/compliance-settings-store.d.ts +44 -0
- package/src/lib/storage/compliance-settings-store.js +78 -0
- package/src/lib/storage/compliance-settings-store.js.map +1 -0
- package/src/lib/storage/do-not-contact-store.d.ts +60 -0
- package/src/lib/storage/do-not-contact-store.js +168 -0
- package/src/lib/storage/do-not-contact-store.js.map +1 -0
- package/src/lib/storage/outreach-records.d.ts +33 -0
- package/src/lib/storage/outreach-records.js +35 -0
- package/src/lib/storage/outreach-records.js.map +1 -0
- package/src/lib/subprocessors.d.ts +48 -0
- package/src/lib/subprocessors.js +70 -0
- package/src/lib/subprocessors.js.map +1 -0
- package/src/lib/transport/gmail-client.d.ts +145 -0
- package/src/lib/transport/gmail-client.js +229 -0
- package/src/lib/transport/gmail-client.js.map +1 -0
- package/src/lib/transport/gmail-errors.d.ts +84 -0
- package/src/lib/transport/gmail-errors.js +138 -0
- package/src/lib/transport/gmail-errors.js.map +1 -0
- package/src/lib/transport/google-oauth.d.ts +138 -0
- package/src/lib/transport/google-oauth.js +247 -0
- package/src/lib/transport/google-oauth.js.map +1 -0
- package/src/lib/transport/http.d.ts +53 -0
- package/src/lib/transport/http.js +79 -0
- package/src/lib/transport/http.js.map +1 -0
- package/src/lib/transport/rfc5322.d.ts +116 -0
- package/src/lib/transport/rfc5322.js +330 -0
- package/src/lib/transport/rfc5322.js.map +1 -0
- package/src/lib/transport/send-message.d.ts +69 -0
- package/src/lib/transport/send-message.js +77 -0
- package/src/lib/transport/send-message.js.map +1 -0
|
@@ -0,0 +1,435 @@
|
|
|
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 { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
18
|
+
import { consentGroupForHost } from "@aglyn/aglyn/app-utils/consent-groups";
|
|
19
|
+
import { mdiAccountMultiplePlusOutline, mdiChevronLeft } from "@aglyn/shared-data-mdi";
|
|
20
|
+
import { MdiIcon } from "@aglyn/shared-ui-jsx";
|
|
21
|
+
import { useSnackbar } from "@aglyn/shared-ui-snackstack";
|
|
22
|
+
import { useUser } from "@aglyn/tenant-feature-instance";
|
|
23
|
+
import { Alert, Button, Card, Dialog, DialogActions, DialogContent, DialogContentText, DialogTitle, Stack, Tab, Tabs, Typography } from "@mui/material";
|
|
24
|
+
import EmptyStateComponent from "@aglyn/shared-ui-jsx/components/empty-state.component";
|
|
25
|
+
import { useState } from "react";
|
|
26
|
+
import { validateOutreachOrgSettings } from "../engine/sequence-validation.js";
|
|
27
|
+
import { outreachMailboxActivationIssue, outreachSequenceMailboxState } from "../model/sequence-draft.js";
|
|
28
|
+
import { OutreachEnrollDialog } from "./enroll-dialog.js";
|
|
29
|
+
import { OutreachEnrollmentsTable } from "./enrollments-table.js";
|
|
30
|
+
import { OutreachLink, OutreachLoading, OutreachLoadProblem, OutreachSequenceStatusChip, useOutreachNavigate } from "./outreach-ui.js";
|
|
31
|
+
import { OutreachSequenceEditor } from "./sequence-editor.js";
|
|
32
|
+
import { OutreachRouteError, useOutreachApi } from "./use-outreach-api.js";
|
|
33
|
+
import { useOutreachEnrollments, useOutreachSequence } from "./use-outreach-data.js";
|
|
34
|
+
/**
|
|
35
|
+
* What stops a sequence being activated, read before anyone clicks: its
|
|
36
|
+
* mailbox not sending, and a footer the organization cannot write yet —
|
|
37
|
+
* each in the words the status route refuses with. Only a finished read
|
|
38
|
+
* says something is missing, so nothing is claimed while one is loading.
|
|
39
|
+
*/ export function outreachActivationBlockers(input) {
|
|
40
|
+
const blockers = [];
|
|
41
|
+
if (input.mailboxes.status === 'ready') {
|
|
42
|
+
var _input_mailboxes_mailboxes_find;
|
|
43
|
+
const mailbox = (_input_mailboxes_mailboxes_find = input.mailboxes.mailboxes.find((entry)=>entry.id === input.sequence.mailboxId)) != null ? _input_mailboxes_mailboxes_find : null;
|
|
44
|
+
const issue = outreachMailboxActivationIssue(input.sequence.mailboxId, mailbox);
|
|
45
|
+
if (issue) {
|
|
46
|
+
blockers.push(issue.code === 'mailbox_not_sending' ? {
|
|
47
|
+
message: issue.message,
|
|
48
|
+
href: input.paths.mailboxes,
|
|
49
|
+
linkLabel: 'Open Mailboxes'
|
|
50
|
+
} : {
|
|
51
|
+
message: issue.message,
|
|
52
|
+
href: input.paths.steps,
|
|
53
|
+
linkLabel: 'Choose a mailbox'
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
if (input.settings.status === 'ready') {
|
|
58
|
+
for (const issue of validateOutreachOrgSettings(input.settings.settings)){
|
|
59
|
+
blockers.push({
|
|
60
|
+
message: issue.message,
|
|
61
|
+
href: input.paths.compliance,
|
|
62
|
+
linkLabel: 'Open Compliance'
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
return blockers;
|
|
67
|
+
}
|
|
68
|
+
/** What an active sequence's page says while its mailbox is not sending. */ const NOT_SENDING = {
|
|
69
|
+
none: 'This sequence has no mailbox, so nothing is sent from it.',
|
|
70
|
+
gone: 'This sequence’s mailbox is no longer connected, so nothing is sent from it.',
|
|
71
|
+
paused: 'This sequence’s mailbox is paused, so nothing is sent until it is resumed.',
|
|
72
|
+
reconnect_required: 'Google stopped accepting this sequence’s mailbox, so nothing is sent until it is reconnected.'
|
|
73
|
+
};
|
|
74
|
+
/** The words an action's button and its snackbar use. */ const ACTIONS = {
|
|
75
|
+
activate: {
|
|
76
|
+
label: 'Activate',
|
|
77
|
+
done: 'Sequence activated.'
|
|
78
|
+
},
|
|
79
|
+
pause: {
|
|
80
|
+
label: 'Pause',
|
|
81
|
+
done: 'Sequence paused.'
|
|
82
|
+
},
|
|
83
|
+
archive: {
|
|
84
|
+
label: 'Archive',
|
|
85
|
+
done: 'Sequence archived.'
|
|
86
|
+
}
|
|
87
|
+
};
|
|
88
|
+
/**
|
|
89
|
+
* One sequence (AGL-2980): its steps in the editor, the people enrolled in
|
|
90
|
+
* it, and what can be done with it — activate, pause, archive, delete a
|
|
91
|
+
* draft, and enroll people in an active one.
|
|
92
|
+
*/ export function OutreachSequenceDetail(props) {
|
|
93
|
+
var _props_mailboxes_mailboxes_find, _ref, _props_org, _ref1;
|
|
94
|
+
const { orgId, sequenceId, sectionPath } = props;
|
|
95
|
+
const api = useOutreachApi(orgId);
|
|
96
|
+
const navigate = useOutreachNavigate();
|
|
97
|
+
const { enqueueSnackbar } = useSnackbar();
|
|
98
|
+
const { data: user } = useUser();
|
|
99
|
+
const loaded = useOutreachSequence(orgId, sequenceId);
|
|
100
|
+
const enrollments = useOutreachEnrollments(props.tab === 'enrollments' ? orgId : null, sequenceId);
|
|
101
|
+
const [busy, setBusy] = useState(false);
|
|
102
|
+
const [refusal, setRefusal] = useState(null);
|
|
103
|
+
const [confirming, setConfirming] = useState(null);
|
|
104
|
+
const [enrolling, setEnrolling] = useState(false);
|
|
105
|
+
const sequence = loaded.data;
|
|
106
|
+
const detailPath = `${sectionPath}/${sequenceId}`;
|
|
107
|
+
const back = /*#__PURE__*/ _jsx(OutreachLink, {
|
|
108
|
+
href: sectionPath,
|
|
109
|
+
children: /*#__PURE__*/ _jsxs(Stack, {
|
|
110
|
+
direction: "row",
|
|
111
|
+
spacing: 0.5,
|
|
112
|
+
component: "span",
|
|
113
|
+
sx: {
|
|
114
|
+
alignItems: 'center',
|
|
115
|
+
display: 'inline-flex'
|
|
116
|
+
},
|
|
117
|
+
children: [
|
|
118
|
+
/*#__PURE__*/ _jsx(MdiIcon, {
|
|
119
|
+
path: mdiChevronLeft.path,
|
|
120
|
+
fontSize: "small"
|
|
121
|
+
}),
|
|
122
|
+
/*#__PURE__*/ _jsx("span", {
|
|
123
|
+
children: "Sequences"
|
|
124
|
+
})
|
|
125
|
+
]
|
|
126
|
+
})
|
|
127
|
+
});
|
|
128
|
+
if (loaded.status === 'loading') return /*#__PURE__*/ _jsx(OutreachLoading, {
|
|
129
|
+
label: "Loading the sequence…"
|
|
130
|
+
});
|
|
131
|
+
if (loaded.status === 'error' || loaded.status === 'refused') {
|
|
132
|
+
return /*#__PURE__*/ _jsx(OutreachLoadProblem, {
|
|
133
|
+
status: loaded.status,
|
|
134
|
+
what: "sequence"
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
if (!sequence) {
|
|
138
|
+
return /*#__PURE__*/ _jsxs(Stack, {
|
|
139
|
+
spacing: 2,
|
|
140
|
+
children: [
|
|
141
|
+
back,
|
|
142
|
+
/*#__PURE__*/ _jsx(Card, {
|
|
143
|
+
variant: "outlined",
|
|
144
|
+
children: /*#__PURE__*/ _jsx(EmptyStateComponent, {
|
|
145
|
+
label: "This sequence no longer exists"
|
|
146
|
+
})
|
|
147
|
+
})
|
|
148
|
+
]
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
const mailbox = (_props_mailboxes_mailboxes_find = props.mailboxes.mailboxes.find((entry)=>entry.id === sequence.mailboxId)) != null ? _props_mailboxes_mailboxes_find : null;
|
|
152
|
+
const mailboxState = props.mailboxes.status === 'ready' ? outreachSequenceMailboxState(sequence.mailboxId, mailbox) : 'sending';
|
|
153
|
+
const activatable = sequence.status === 'draft' || sequence.status === 'paused';
|
|
154
|
+
const blockers = activatable ? outreachActivationBlockers({
|
|
155
|
+
sequence,
|
|
156
|
+
mailboxes: props.mailboxes,
|
|
157
|
+
settings: props.settings,
|
|
158
|
+
paths: {
|
|
159
|
+
steps: detailPath,
|
|
160
|
+
mailboxes: props.mailboxesPath,
|
|
161
|
+
compliance: props.compliancePath
|
|
162
|
+
}
|
|
163
|
+
}) : [];
|
|
164
|
+
// Enrolling onto a mailbox that is gone is refused by the route; a paused
|
|
165
|
+
// one only makes the new people wait with everyone else.
|
|
166
|
+
const canEnroll = sequence.status === 'active' && mailboxState !== 'gone' && mailboxState !== 'none';
|
|
167
|
+
const act = async (action)=>{
|
|
168
|
+
setBusy(true);
|
|
169
|
+
setRefusal(null);
|
|
170
|
+
try {
|
|
171
|
+
const answer = await api.setSequenceStatus(sequence.id, action);
|
|
172
|
+
enqueueSnackbar(action === 'archive' && answer.stoppedEnrollments ? `${ACTIONS.archive.done} ${answer.stoppedEnrollments} ${answer.stoppedEnrollments === 1 ? 'person was' : 'people were'} stopped.` : ACTIONS[action].done, {
|
|
173
|
+
variant: 'success'
|
|
174
|
+
});
|
|
175
|
+
} catch (error) {
|
|
176
|
+
setRefusal({
|
|
177
|
+
message: error.message,
|
|
178
|
+
issues: error instanceof OutreachRouteError ? error.issues.filter((issue)=>'path' in issue) : []
|
|
179
|
+
});
|
|
180
|
+
} finally{
|
|
181
|
+
setBusy(false);
|
|
182
|
+
}
|
|
183
|
+
};
|
|
184
|
+
const remove = async ()=>{
|
|
185
|
+
setBusy(true);
|
|
186
|
+
setRefusal(null);
|
|
187
|
+
try {
|
|
188
|
+
await api.deleteSequence(sequence.id);
|
|
189
|
+
enqueueSnackbar('Sequence deleted.', {
|
|
190
|
+
variant: 'success'
|
|
191
|
+
});
|
|
192
|
+
navigate(sectionPath);
|
|
193
|
+
} catch (error) {
|
|
194
|
+
setRefusal({
|
|
195
|
+
message: error.message,
|
|
196
|
+
issues: []
|
|
197
|
+
});
|
|
198
|
+
setBusy(false);
|
|
199
|
+
}
|
|
200
|
+
};
|
|
201
|
+
const enrollButton = /*#__PURE__*/ _jsx(Button, {
|
|
202
|
+
variant: "contained",
|
|
203
|
+
startIcon: /*#__PURE__*/ _jsx(MdiIcon, {
|
|
204
|
+
path: mdiAccountMultiplePlusOutline.path,
|
|
205
|
+
fontSize: "small"
|
|
206
|
+
}),
|
|
207
|
+
disabled: !canEnroll,
|
|
208
|
+
onClick: ()=>setEnrolling(true),
|
|
209
|
+
children: "Enroll people"
|
|
210
|
+
});
|
|
211
|
+
return /*#__PURE__*/ _jsxs(Stack, {
|
|
212
|
+
spacing: 2,
|
|
213
|
+
children: [
|
|
214
|
+
back,
|
|
215
|
+
/*#__PURE__*/ _jsxs(Stack, {
|
|
216
|
+
direction: {
|
|
217
|
+
xs: 'column',
|
|
218
|
+
md: 'row'
|
|
219
|
+
},
|
|
220
|
+
spacing: 1.5,
|
|
221
|
+
sx: {
|
|
222
|
+
alignItems: {
|
|
223
|
+
md: 'center'
|
|
224
|
+
},
|
|
225
|
+
justifyContent: 'space-between'
|
|
226
|
+
},
|
|
227
|
+
children: [
|
|
228
|
+
/*#__PURE__*/ _jsxs(Stack, {
|
|
229
|
+
direction: "row",
|
|
230
|
+
spacing: 1,
|
|
231
|
+
sx: {
|
|
232
|
+
alignItems: 'center',
|
|
233
|
+
minWidth: 0
|
|
234
|
+
},
|
|
235
|
+
children: [
|
|
236
|
+
/*#__PURE__*/ _jsx(Typography, {
|
|
237
|
+
variant: "h5",
|
|
238
|
+
component: "h2",
|
|
239
|
+
sx: {
|
|
240
|
+
wordBreak: 'break-word'
|
|
241
|
+
},
|
|
242
|
+
children: sequence.name
|
|
243
|
+
}),
|
|
244
|
+
/*#__PURE__*/ _jsx(OutreachSequenceStatusChip, {
|
|
245
|
+
status: sequence.status
|
|
246
|
+
})
|
|
247
|
+
]
|
|
248
|
+
}),
|
|
249
|
+
/*#__PURE__*/ _jsxs(Stack, {
|
|
250
|
+
direction: "row",
|
|
251
|
+
spacing: 1,
|
|
252
|
+
sx: {
|
|
253
|
+
flexWrap: 'wrap',
|
|
254
|
+
rowGap: 1
|
|
255
|
+
},
|
|
256
|
+
children: [
|
|
257
|
+
activatable ? /*#__PURE__*/ _jsx(Button, {
|
|
258
|
+
variant: "outlined",
|
|
259
|
+
disabled: busy || blockers.length > 0,
|
|
260
|
+
onClick: ()=>void act('activate'),
|
|
261
|
+
children: ACTIONS.activate.label
|
|
262
|
+
}) : null,
|
|
263
|
+
sequence.status === 'active' ? /*#__PURE__*/ _jsx(Button, {
|
|
264
|
+
variant: "outlined",
|
|
265
|
+
disabled: busy,
|
|
266
|
+
onClick: ()=>void act('pause'),
|
|
267
|
+
children: ACTIONS.pause.label
|
|
268
|
+
}) : null,
|
|
269
|
+
sequence.status !== 'archived' ? /*#__PURE__*/ _jsx(Button, {
|
|
270
|
+
variant: "outlined",
|
|
271
|
+
color: "error",
|
|
272
|
+
disabled: busy,
|
|
273
|
+
onClick: ()=>setConfirming('archive'),
|
|
274
|
+
children: ACTIONS.archive.label
|
|
275
|
+
}) : null,
|
|
276
|
+
sequence.status === 'draft' ? /*#__PURE__*/ _jsx(Button, {
|
|
277
|
+
variant: "text",
|
|
278
|
+
color: "error",
|
|
279
|
+
disabled: busy,
|
|
280
|
+
onClick: ()=>setConfirming('delete'),
|
|
281
|
+
children: "Delete"
|
|
282
|
+
}) : null,
|
|
283
|
+
sequence.status === 'active' ? enrollButton : null
|
|
284
|
+
]
|
|
285
|
+
})
|
|
286
|
+
]
|
|
287
|
+
}),
|
|
288
|
+
refusal ? /*#__PURE__*/ _jsx(Alert, {
|
|
289
|
+
severity: "error",
|
|
290
|
+
onClose: ()=>setRefusal(null),
|
|
291
|
+
children: /*#__PURE__*/ _jsxs(Stack, {
|
|
292
|
+
spacing: 0.5,
|
|
293
|
+
children: [
|
|
294
|
+
/*#__PURE__*/ _jsx("span", {
|
|
295
|
+
children: refusal.message
|
|
296
|
+
}),
|
|
297
|
+
refusal.issues.length > 1 ? /*#__PURE__*/ _jsx(Stack, {
|
|
298
|
+
component: "ul",
|
|
299
|
+
spacing: 0.25,
|
|
300
|
+
sx: {
|
|
301
|
+
m: 0,
|
|
302
|
+
pl: 2.5
|
|
303
|
+
},
|
|
304
|
+
children: refusal.issues.slice(1).map((issue)=>/*#__PURE__*/ _jsx("li", {
|
|
305
|
+
children: issue.message
|
|
306
|
+
}, `${issue.path}:${issue.code}`))
|
|
307
|
+
}) : null
|
|
308
|
+
]
|
|
309
|
+
})
|
|
310
|
+
}) : null,
|
|
311
|
+
blockers.length ? /*#__PURE__*/ _jsx(Alert, {
|
|
312
|
+
severity: "warning",
|
|
313
|
+
"data-testid": "outreach-activation-blockers",
|
|
314
|
+
children: /*#__PURE__*/ _jsxs(Stack, {
|
|
315
|
+
spacing: 0.5,
|
|
316
|
+
children: [
|
|
317
|
+
/*#__PURE__*/ _jsx("span", {
|
|
318
|
+
children: sequence.status === 'draft' ? 'A draft sends nothing, and this one can’t be activated yet:' : 'This sequence can’t be activated again yet:'
|
|
319
|
+
}),
|
|
320
|
+
/*#__PURE__*/ _jsx(Stack, {
|
|
321
|
+
component: "ul",
|
|
322
|
+
spacing: 0.25,
|
|
323
|
+
sx: {
|
|
324
|
+
m: 0,
|
|
325
|
+
pl: 2.5
|
|
326
|
+
},
|
|
327
|
+
children: blockers.map((blocker)=>/*#__PURE__*/ _jsxs("li", {
|
|
328
|
+
children: [
|
|
329
|
+
blocker.message,
|
|
330
|
+
' ',
|
|
331
|
+
/*#__PURE__*/ _jsx(OutreachLink, {
|
|
332
|
+
href: blocker.href,
|
|
333
|
+
children: blocker.linkLabel
|
|
334
|
+
})
|
|
335
|
+
]
|
|
336
|
+
}, blocker.message))
|
|
337
|
+
})
|
|
338
|
+
]
|
|
339
|
+
})
|
|
340
|
+
}) : sequence.status === 'draft' ? /*#__PURE__*/ _jsx(Alert, {
|
|
341
|
+
severity: "info",
|
|
342
|
+
children: "A draft sends nothing. Activate it to enroll people."
|
|
343
|
+
}) : null,
|
|
344
|
+
sequence.status === 'active' && mailboxState !== 'sending' ? /*#__PURE__*/ _jsxs(Alert, {
|
|
345
|
+
severity: "warning",
|
|
346
|
+
children: [
|
|
347
|
+
NOT_SENDING[mailboxState],
|
|
348
|
+
' ',
|
|
349
|
+
/*#__PURE__*/ _jsx(OutreachLink, {
|
|
350
|
+
href: props.mailboxesPath,
|
|
351
|
+
children: "Open Mailboxes"
|
|
352
|
+
})
|
|
353
|
+
]
|
|
354
|
+
}) : null,
|
|
355
|
+
/*#__PURE__*/ _jsxs(Tabs, {
|
|
356
|
+
value: props.tab,
|
|
357
|
+
onChange: (_event, next)=>navigate(next === 'steps' ? detailPath : `${detailPath}/enrollments`),
|
|
358
|
+
"aria-label": "Sequence",
|
|
359
|
+
children: [
|
|
360
|
+
/*#__PURE__*/ _jsx(Tab, {
|
|
361
|
+
value: "steps",
|
|
362
|
+
label: "Steps"
|
|
363
|
+
}),
|
|
364
|
+
/*#__PURE__*/ _jsx(Tab, {
|
|
365
|
+
value: "enrollments",
|
|
366
|
+
label: "Enrollments"
|
|
367
|
+
})
|
|
368
|
+
]
|
|
369
|
+
}),
|
|
370
|
+
props.tab === 'steps' ? /*#__PURE__*/ _jsx(OutreachSequenceEditor, {
|
|
371
|
+
orgId: orgId,
|
|
372
|
+
orgMount: props.orgMount,
|
|
373
|
+
sequence: sequence,
|
|
374
|
+
settings: props.settings,
|
|
375
|
+
mailboxes: props.mailboxes,
|
|
376
|
+
mailboxesPath: props.mailboxesPath,
|
|
377
|
+
onSaved: ()=>undefined
|
|
378
|
+
}) : /*#__PURE__*/ _jsx(OutreachEnrollmentsTable, {
|
|
379
|
+
enrollments: enrollments,
|
|
380
|
+
steps: sequence.steps,
|
|
381
|
+
timeZone: (_ref = mailbox == null ? void 0 : mailbox.timezone) != null ? _ref : null,
|
|
382
|
+
api: api,
|
|
383
|
+
enrollAction: sequence.status === 'active' ? enrollButton : undefined
|
|
384
|
+
}),
|
|
385
|
+
/*#__PURE__*/ _jsx(OutreachEnrollDialog, {
|
|
386
|
+
open: enrolling,
|
|
387
|
+
onClose: ()=>setEnrolling(false),
|
|
388
|
+
orgId: orgId,
|
|
389
|
+
sequence: sequence,
|
|
390
|
+
contactGroupId: sequence.hostId ? consentGroupForHost((_props_org = props.org) != null ? _props_org : null, sequence.hostId).groupId : '',
|
|
391
|
+
uid: (_ref1 = user == null ? void 0 : user.uid) != null ? _ref1 : null,
|
|
392
|
+
api: api
|
|
393
|
+
}),
|
|
394
|
+
/*#__PURE__*/ _jsxs(Dialog, {
|
|
395
|
+
open: Boolean(confirming),
|
|
396
|
+
onClose: ()=>setConfirming(null),
|
|
397
|
+
fullWidth: true,
|
|
398
|
+
maxWidth: "xs",
|
|
399
|
+
children: [
|
|
400
|
+
/*#__PURE__*/ _jsx(DialogTitle, {
|
|
401
|
+
children: confirming === 'delete' ? 'Delete this draft?' : 'Archive this sequence?'
|
|
402
|
+
}),
|
|
403
|
+
/*#__PURE__*/ _jsx(DialogContent, {
|
|
404
|
+
children: /*#__PURE__*/ _jsx(DialogContentText, {
|
|
405
|
+
children: confirming === 'delete' ? 'It is removed for good. Nobody was ever enrolled in it.' : 'Archiving is final. Everyone still in it is stopped, and it takes no one new.'
|
|
406
|
+
})
|
|
407
|
+
}),
|
|
408
|
+
/*#__PURE__*/ _jsxs(DialogActions, {
|
|
409
|
+
children: [
|
|
410
|
+
/*#__PURE__*/ _jsx(Button, {
|
|
411
|
+
onClick: ()=>setConfirming(null),
|
|
412
|
+
children: "Cancel"
|
|
413
|
+
}),
|
|
414
|
+
/*#__PURE__*/ _jsx(Button, {
|
|
415
|
+
color: "error",
|
|
416
|
+
variant: "contained",
|
|
417
|
+
onClick: ()=>{
|
|
418
|
+
const chosen = confirming;
|
|
419
|
+
setConfirming(null);
|
|
420
|
+
if (chosen === 'delete') void remove();
|
|
421
|
+
else void act('archive');
|
|
422
|
+
},
|
|
423
|
+
children: confirming === 'delete' ? 'Delete' : 'Archive'
|
|
424
|
+
})
|
|
425
|
+
]
|
|
426
|
+
})
|
|
427
|
+
]
|
|
428
|
+
})
|
|
429
|
+
]
|
|
430
|
+
});
|
|
431
|
+
}
|
|
432
|
+
OutreachSequenceDetail.displayName = 'OutreachSequenceDetail';
|
|
433
|
+
export default OutreachSequenceDetail;
|
|
434
|
+
|
|
435
|
+
//# sourceMappingURL=sequence-detail.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../../../libs/plugins/outreach/src/lib/components/sequence-detail.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 { consentGroupForHost } from '@aglyn/aglyn/app-utils/consent-groups'\nimport type { ConsolePluginOrgMount } from '@aglyn/aglyn'\nimport {\n mdiAccountMultiplePlusOutline,\n mdiChevronLeft,\n} from '@aglyn/shared-data-mdi'\nimport { MdiIcon } from '@aglyn/shared-ui-jsx'\nimport { useSnackbar } from '@aglyn/shared-ui-snackstack'\nimport { useUser } from '@aglyn/tenant-feature-instance'\nimport {\n Alert,\n Button,\n Card,\n Dialog,\n DialogActions,\n DialogContent,\n DialogContentText,\n DialogTitle,\n Stack,\n Tab,\n Tabs,\n Typography,\n} from '@mui/material'\nimport EmptyStateComponent from '@aglyn/shared-ui-jsx/components/empty-state.component'\nimport { useState } from 'react'\nimport { validateOutreachOrgSettings } from '../engine/sequence-validation'\nimport type { OutreachSequenceAction } from '../model/outreach-api'\nimport {\n outreachMailboxActivationIssue,\n outreachSequenceMailboxState,\n type OutreachSequenceIssue,\n type OutreachSequenceMailboxState,\n} from '../model/sequence-draft'\nimport { OutreachEnrollDialog } from './enroll-dialog'\nimport { OutreachEnrollmentsTable } from './enrollments-table'\nimport {\n OutreachLink,\n OutreachLoading,\n OutreachLoadProblem,\n OutreachSequenceStatusChip,\n useOutreachNavigate,\n} from './outreach-ui'\nimport { OutreachSequenceEditor } from './sequence-editor'\nimport { OutreachRouteError, useOutreachApi } from './use-outreach-api'\nimport {\n useOutreachEnrollments,\n useOutreachSequence,\n} from './use-outreach-data'\nimport type { OutreachMailboxesResult } from './use-outreach-mailboxes'\nimport type { OutreachSettingsLoad } from './use-outreach-settings'\n\nexport type OutreachSequenceTab = 'steps' | 'enrollments'\n\nexport interface OutreachSequenceDetailProps {\n orgId: string\n orgMount?: ConsolePluginOrgMount\n /** The organization document the shell loaded: whose consent groups name a site's contacts. */\n org?: Record<string, unknown> | null\n /** Where the Sequences section lives: `/[orgSlug]/outreach/sequences`. */\n sectionPath: string\n sequenceId: string\n tab: OutreachSequenceTab\n settings: OutreachSettingsLoad\n mailboxes: OutreachMailboxesResult\n /** The Mailboxes section: where a mailbox is connected, resumed or reconnected. */\n mailboxesPath: string\n /** The Compliance section: where the footer's legal name and address are set. */\n compliancePath: string\n}\n\n/** Something activation would refuse, and where it is put right. */\nexport interface OutreachActivationBlocker {\n message: string\n href: string\n linkLabel: string\n}\n\n/**\n * What stops a sequence being activated, read before anyone clicks: its\n * mailbox not sending, and a footer the organization cannot write yet —\n * each in the words the status route refuses with. Only a finished read\n * says something is missing, so nothing is claimed while one is loading.\n */\nexport function outreachActivationBlockers(input: {\n sequence: { mailboxId: string }\n mailboxes: OutreachMailboxesResult\n settings: OutreachSettingsLoad\n paths: { steps: string; mailboxes: string; compliance: string }\n}): OutreachActivationBlocker[] {\n const blockers: OutreachActivationBlocker[] = []\n if (input.mailboxes.status === 'ready') {\n const mailbox =\n input.mailboxes.mailboxes.find((entry) => entry.id === input.sequence.mailboxId) ?? null\n const issue = outreachMailboxActivationIssue(input.sequence.mailboxId, mailbox)\n if (issue) {\n blockers.push(\n issue.code === 'mailbox_not_sending'\n ? { message: issue.message, href: input.paths.mailboxes, linkLabel: 'Open Mailboxes' }\n : { message: issue.message, href: input.paths.steps, linkLabel: 'Choose a mailbox' },\n )\n }\n }\n if (input.settings.status === 'ready') {\n for (const issue of validateOutreachOrgSettings(input.settings.settings)) {\n blockers.push({ message: issue.message, href: input.paths.compliance, linkLabel: 'Open Compliance' })\n }\n }\n return blockers\n}\n\n/** What an active sequence's page says while its mailbox is not sending. */\nconst NOT_SENDING: Record<Exclude<OutreachSequenceMailboxState, 'sending'>, string> = {\n none: 'This sequence has no mailbox, so nothing is sent from it.',\n gone: 'This sequence’s mailbox is no longer connected, so nothing is sent from it.',\n paused: 'This sequence’s mailbox is paused, so nothing is sent until it is resumed.',\n reconnect_required:\n 'Google stopped accepting this sequence’s mailbox, so nothing is sent until it is reconnected.',\n}\n\n/** The words an action's button and its snackbar use. */\nconst ACTIONS: Record<OutreachSequenceAction, { label: string; done: string }> =\n {\n activate: { label: 'Activate', done: 'Sequence activated.' },\n pause: { label: 'Pause', done: 'Sequence paused.' },\n archive: { label: 'Archive', done: 'Sequence archived.' },\n }\n\n/**\n * One sequence (AGL-2980): its steps in the editor, the people enrolled in\n * it, and what can be done with it — activate, pause, archive, delete a\n * draft, and enroll people in an active one.\n */\nexport function OutreachSequenceDetail(props: OutreachSequenceDetailProps) {\n const { orgId, sequenceId, sectionPath } = props\n const api = useOutreachApi(orgId)\n const navigate = useOutreachNavigate()\n const { enqueueSnackbar } = useSnackbar()\n const { data: user } = useUser()\n const loaded = useOutreachSequence(orgId, sequenceId)\n const enrollments = useOutreachEnrollments(\n props.tab === 'enrollments' ? orgId : null,\n sequenceId,\n )\n const [busy, setBusy] = useState(false)\n const [refusal, setRefusal] = useState<{\n message: string\n issues: OutreachSequenceIssue[]\n } | null>(null)\n const [confirming, setConfirming] = useState<'archive' | 'delete' | null>(\n null,\n )\n const [enrolling, setEnrolling] = useState(false)\n\n const sequence = loaded.data\n const detailPath = `${sectionPath}/${sequenceId}`\n const back = (\n <OutreachLink href={sectionPath}>\n <Stack\n direction=\"row\"\n spacing={0.5}\n component=\"span\"\n sx={{ alignItems: 'center', display: 'inline-flex' }}\n >\n <MdiIcon path={mdiChevronLeft.path} fontSize=\"small\" />\n <span>Sequences</span>\n </Stack>\n </OutreachLink>\n )\n\n if (loaded.status === 'loading')\n return <OutreachLoading label=\"Loading the sequence…\" />\n if (loaded.status === 'error' || loaded.status === 'refused') {\n return <OutreachLoadProblem status={loaded.status} what=\"sequence\" />\n }\n if (!sequence) {\n return (\n <Stack spacing={2}>\n {back}\n <Card variant=\"outlined\">\n <EmptyStateComponent label=\"This sequence no longer exists\" />\n </Card>\n </Stack>\n )\n }\n\n const mailbox =\n props.mailboxes.mailboxes.find((entry) => entry.id === sequence.mailboxId) ??\n null\n const mailboxState =\n props.mailboxes.status === 'ready'\n ? outreachSequenceMailboxState(sequence.mailboxId, mailbox)\n : 'sending'\n const activatable = sequence.status === 'draft' || sequence.status === 'paused'\n const blockers = activatable\n ? outreachActivationBlockers({\n sequence,\n mailboxes: props.mailboxes,\n settings: props.settings,\n paths: {\n steps: detailPath,\n mailboxes: props.mailboxesPath,\n compliance: props.compliancePath,\n },\n })\n : []\n // Enrolling onto a mailbox that is gone is refused by the route; a paused\n // one only makes the new people wait with everyone else.\n const canEnroll =\n sequence.status === 'active' &&\n mailboxState !== 'gone' &&\n mailboxState !== 'none'\n const act = async (action: OutreachSequenceAction) => {\n setBusy(true)\n setRefusal(null)\n try {\n const answer = await api.setSequenceStatus(sequence.id, action)\n enqueueSnackbar(\n action === 'archive' && answer.stoppedEnrollments\n ? `${ACTIONS.archive.done} ${answer.stoppedEnrollments} ${answer.stoppedEnrollments === 1 ? 'person was' : 'people were'} stopped.`\n : ACTIONS[action].done,\n { variant: 'success' },\n )\n } catch (error) {\n setRefusal({\n message: (error as Error).message,\n issues:\n error instanceof OutreachRouteError\n ? error.issues.filter(\n (issue): issue is OutreachSequenceIssue => 'path' in issue,\n )\n : [],\n })\n } finally {\n setBusy(false)\n }\n }\n const remove = async () => {\n setBusy(true)\n setRefusal(null)\n try {\n await api.deleteSequence(sequence.id)\n enqueueSnackbar('Sequence deleted.', { variant: 'success' })\n navigate(sectionPath)\n } catch (error) {\n setRefusal({ message: (error as Error).message, issues: [] })\n setBusy(false)\n }\n }\n\n const enrollButton = (\n <Button\n variant=\"contained\"\n startIcon={\n <MdiIcon path={mdiAccountMultiplePlusOutline.path} fontSize=\"small\" />\n }\n disabled={!canEnroll}\n onClick={() => setEnrolling(true)}\n >\n Enroll people\n </Button>\n )\n\n return (\n <Stack spacing={2}>\n {back}\n <Stack\n direction={{ xs: 'column', md: 'row' }}\n spacing={1.5}\n sx={{ alignItems: { md: 'center' }, justifyContent: 'space-between' }}\n >\n <Stack\n direction=\"row\"\n spacing={1}\n sx={{ alignItems: 'center', minWidth: 0 }}\n >\n <Typography\n variant=\"h5\"\n component=\"h2\"\n sx={{ wordBreak: 'break-word' }}\n >\n {sequence.name}\n </Typography>\n <OutreachSequenceStatusChip status={sequence.status} />\n </Stack>\n <Stack direction=\"row\" spacing={1} sx={{ flexWrap: 'wrap', rowGap: 1 }}>\n {activatable ? (\n <Button\n variant=\"outlined\"\n disabled={busy || blockers.length > 0}\n onClick={() => void act('activate')}\n >\n {ACTIONS.activate.label}\n </Button>\n ) : null}\n {sequence.status === 'active' ? (\n <Button\n variant=\"outlined\"\n disabled={busy}\n onClick={() => void act('pause')}\n >\n {ACTIONS.pause.label}\n </Button>\n ) : null}\n {sequence.status !== 'archived' ? (\n <Button\n variant=\"outlined\"\n color=\"error\"\n disabled={busy}\n onClick={() => setConfirming('archive')}\n >\n {ACTIONS.archive.label}\n </Button>\n ) : null}\n {sequence.status === 'draft' ? (\n <Button\n variant=\"text\"\n color=\"error\"\n disabled={busy}\n onClick={() => setConfirming('delete')}\n >\n Delete\n </Button>\n ) : null}\n {sequence.status === 'active' ? enrollButton : null}\n </Stack>\n </Stack>\n\n {refusal ? (\n <Alert severity=\"error\" onClose={() => setRefusal(null)}>\n <Stack spacing={0.5}>\n <span>{refusal.message}</span>\n {refusal.issues.length > 1 ? (\n <Stack component=\"ul\" spacing={0.25} sx={{ m: 0, pl: 2.5 }}>\n {refusal.issues.slice(1).map((issue) => (\n <li key={`${issue.path}:${issue.code}`}>{issue.message}</li>\n ))}\n </Stack>\n ) : null}\n </Stack>\n </Alert>\n ) : null}\n {blockers.length ? (\n <Alert severity=\"warning\" data-testid=\"outreach-activation-blockers\">\n <Stack spacing={0.5}>\n <span>\n {sequence.status === 'draft'\n ? 'A draft sends nothing, and this one can’t be activated yet:'\n : 'This sequence can’t be activated again yet:'}\n </span>\n <Stack component=\"ul\" spacing={0.25} sx={{ m: 0, pl: 2.5 }}>\n {blockers.map((blocker) => (\n <li key={blocker.message}>\n {blocker.message}{' '}\n <OutreachLink href={blocker.href}>{blocker.linkLabel}</OutreachLink>\n </li>\n ))}\n </Stack>\n </Stack>\n </Alert>\n ) : sequence.status === 'draft' ? (\n <Alert severity=\"info\">\n A draft sends nothing. Activate it to enroll people.\n </Alert>\n ) : null}\n {sequence.status === 'active' && mailboxState !== 'sending' ? (\n <Alert severity=\"warning\">\n {NOT_SENDING[mailboxState]}{' '}\n <OutreachLink href={props.mailboxesPath}>Open Mailboxes</OutreachLink>\n </Alert>\n ) : null}\n\n <Tabs\n value={props.tab}\n onChange={(_event, next: OutreachSequenceTab) =>\n navigate(next === 'steps' ? detailPath : `${detailPath}/enrollments`)\n }\n aria-label=\"Sequence\"\n >\n <Tab value=\"steps\" label=\"Steps\" />\n <Tab value=\"enrollments\" label=\"Enrollments\" />\n </Tabs>\n\n {props.tab === 'steps' ? (\n <OutreachSequenceEditor\n orgId={orgId}\n orgMount={props.orgMount}\n sequence={sequence}\n settings={props.settings}\n mailboxes={props.mailboxes}\n mailboxesPath={props.mailboxesPath}\n onSaved={() => undefined}\n />\n ) : (\n <OutreachEnrollmentsTable\n enrollments={enrollments}\n steps={sequence.steps}\n timeZone={mailbox?.timezone ?? null}\n api={api}\n enrollAction={sequence.status === 'active' ? enrollButton : undefined}\n />\n )}\n\n <OutreachEnrollDialog\n open={enrolling}\n onClose={() => setEnrolling(false)}\n orgId={orgId}\n sequence={sequence}\n contactGroupId={\n sequence.hostId\n ? consentGroupForHost(props.org ?? null, sequence.hostId).groupId\n : ''\n }\n uid={user?.uid ?? null}\n api={api}\n />\n\n <Dialog\n open={Boolean(confirming)}\n onClose={() => setConfirming(null)}\n fullWidth\n maxWidth=\"xs\"\n >\n <DialogTitle>\n {confirming === 'delete'\n ? 'Delete this draft?'\n : 'Archive this sequence?'}\n </DialogTitle>\n <DialogContent>\n <DialogContentText>\n {confirming === 'delete'\n ? 'It is removed for good. Nobody was ever enrolled in it.'\n : 'Archiving is final. Everyone still in it is stopped, and it takes no one new.'}\n </DialogContentText>\n </DialogContent>\n <DialogActions>\n <Button onClick={() => setConfirming(null)}>Cancel</Button>\n <Button\n color=\"error\"\n variant=\"contained\"\n onClick={() => {\n const chosen = confirming\n setConfirming(null)\n if (chosen === 'delete') void remove()\n else void act('archive')\n }}\n >\n {confirming === 'delete' ? 'Delete' : 'Archive'}\n </Button>\n </DialogActions>\n </Dialog>\n </Stack>\n )\n}\nOutreachSequenceDetail.displayName = 'OutreachSequenceDetail'\n\nexport default OutreachSequenceDetail\n"],"names":["consentGroupForHost","mdiAccountMultiplePlusOutline","mdiChevronLeft","MdiIcon","useSnackbar","useUser","Alert","Button","Card","Dialog","DialogActions","DialogContent","DialogContentText","DialogTitle","Stack","Tab","Tabs","Typography","EmptyStateComponent","useState","validateOutreachOrgSettings","outreachMailboxActivationIssue","outreachSequenceMailboxState","OutreachEnrollDialog","OutreachEnrollmentsTable","OutreachLink","OutreachLoading","OutreachLoadProblem","OutreachSequenceStatusChip","useOutreachNavigate","OutreachSequenceEditor","OutreachRouteError","useOutreachApi","useOutreachEnrollments","useOutreachSequence","outreachActivationBlockers","input","blockers","mailboxes","status","mailbox","find","entry","id","sequence","mailboxId","issue","push","code","message","href","paths","linkLabel","steps","settings","compliance","NOT_SENDING","none","gone","paused","reconnect_required","ACTIONS","activate","label","done","pause","archive","OutreachSequenceDetail","props","orgId","sequenceId","sectionPath","api","navigate","enqueueSnackbar","data","user","loaded","enrollments","tab","busy","setBusy","refusal","setRefusal","confirming","setConfirming","enrolling","setEnrolling","detailPath","back","direction","spacing","component","sx","alignItems","display","path","fontSize","span","what","variant","mailboxState","activatable","mailboxesPath","compliancePath","canEnroll","act","action","answer","setSequenceStatus","stoppedEnrollments","error","issues","filter","remove","deleteSequence","enrollButton","startIcon","disabled","onClick","xs","md","justifyContent","minWidth","wordBreak","name","flexWrap","rowGap","length","color","severity","onClose","m","pl","slice","map","li","data-testid","blocker","value","onChange","_event","next","aria-label","orgMount","onSaved","undefined","timeZone","timezone","enrollAction","open","contactGroupId","hostId","org","groupId","uid","Boolean","fullWidth","maxWidth","chosen","displayName"],"mappings":"AAAA;;;;;;;;;;;;;;;CAeC,GACD;;AAEA,SAASA,mBAAmB,QAAQ,wCAAuC;AAE3E,SACEC,6BAA6B,EAC7BC,cAAc,QACT,yBAAwB;AAC/B,SAASC,OAAO,QAAQ,uBAAsB;AAC9C,SAASC,WAAW,QAAQ,8BAA6B;AACzD,SAASC,OAAO,QAAQ,iCAAgC;AACxD,SACEC,KAAK,EACLC,MAAM,EACNC,IAAI,EACJC,MAAM,EACNC,aAAa,EACbC,aAAa,EACbC,iBAAiB,EACjBC,WAAW,EACXC,KAAK,EACLC,GAAG,EACHC,IAAI,EACJC,UAAU,QACL,gBAAe;AACtB,OAAOC,yBAAyB,wDAAuD;AACvF,SAASC,QAAQ,QAAQ,QAAO;AAChC,SAASC,2BAA2B,QAAQ,mCAA+B;AAE3E,SACEC,8BAA8B,EAC9BC,4BAA4B,QAGvB,6BAAyB;AAChC,SAASC,oBAAoB,QAAQ,qBAAiB;AACtD,SAASC,wBAAwB,QAAQ,yBAAqB;AAC9D,SACEC,YAAY,EACZC,eAAe,EACfC,mBAAmB,EACnBC,0BAA0B,EAC1BC,mBAAmB,QACd,mBAAe;AACtB,SAASC,sBAAsB,QAAQ,uBAAmB;AAC1D,SAASC,kBAAkB,EAAEC,cAAc,QAAQ,wBAAoB;AACvE,SACEC,sBAAsB,EACtBC,mBAAmB,QACd,yBAAqB;AA8B5B;;;;;CAKC,GACD,OAAO,SAASC,2BAA2BC,KAK1C;IACC,MAAMC,WAAwC,EAAE;IAChD,IAAID,MAAME,SAAS,CAACC,MAAM,KAAK,SAAS;YAEpCH;QADF,MAAMI,WACJJ,kCAAAA,MAAME,SAAS,CAACA,SAAS,CAACG,IAAI,CAAC,CAACC,QAAUA,MAAMC,EAAE,KAAKP,MAAMQ,QAAQ,CAACC,SAAS,aAA/ET,kCAAoF;QACtF,MAAMU,QAAQzB,+BAA+Be,MAAMQ,QAAQ,CAACC,SAAS,EAAEL;QACvE,IAAIM,OAAO;YACTT,SAASU,IAAI,CACXD,MAAME,IAAI,KAAK,wBACX;gBAAEC,SAASH,MAAMG,OAAO;gBAAEC,MAAMd,MAAMe,KAAK,CAACb,SAAS;gBAAEc,WAAW;YAAiB,IACnF;gBAAEH,SAASH,MAAMG,OAAO;gBAAEC,MAAMd,MAAMe,KAAK,CAACE,KAAK;gBAAED,WAAW;YAAmB;QAEzF;IACF;IACA,IAAIhB,MAAMkB,QAAQ,CAACf,MAAM,KAAK,SAAS;QACrC,KAAK,MAAMO,SAAS1B,4BAA4BgB,MAAMkB,QAAQ,CAACA,QAAQ,EAAG;YACxEjB,SAASU,IAAI,CAAC;gBAAEE,SAASH,MAAMG,OAAO;gBAAEC,MAAMd,MAAMe,KAAK,CAACI,UAAU;gBAAEH,WAAW;YAAkB;QACrG;IACF;IACA,OAAOf;AACT;AAEA,0EAA0E,GAC1E,MAAMmB,cAAgF;IACpFC,MAAM;IACNC,MAAM;IACNC,QAAQ;IACRC,oBACE;AACJ;AAEA,uDAAuD,GACvD,MAAMC,UACJ;IACEC,UAAU;QAAEC,OAAO;QAAYC,MAAM;IAAsB;IAC3DC,OAAO;QAAEF,OAAO;QAASC,MAAM;IAAmB;IAClDE,SAAS;QAAEH,OAAO;QAAWC,MAAM;IAAqB;AAC1D;AAEF;;;;CAIC,GACD,OAAO,SAASG,uBAAuBC,KAAkC;QAsDrEA,uCA+N8BA;IApRhC,MAAM,EAAEC,KAAK,EAAEC,UAAU,EAAEC,WAAW,EAAE,GAAGH;IAC3C,MAAMI,MAAMxC,eAAeqC;IAC3B,MAAMI,WAAW5C;IACjB,MAAM,EAAE6C,eAAe,EAAE,GAAGtE;IAC5B,MAAM,EAAEuE,MAAMC,IAAI,EAAE,GAAGvE;IACvB,MAAMwE,SAAS3C,oBAAoBmC,OAAOC;IAC1C,MAAMQ,cAAc7C,uBAClBmC,MAAMW,GAAG,KAAK,gBAAgBV,QAAQ,MACtCC;IAEF,MAAM,CAACU,MAAMC,QAAQ,GAAG9D,SAAS;IACjC,MAAM,CAAC+D,SAASC,WAAW,GAAGhE,SAGpB;IACV,MAAM,CAACiE,YAAYC,cAAc,GAAGlE,SAClC;IAEF,MAAM,CAACmE,WAAWC,aAAa,GAAGpE,SAAS;IAE3C,MAAMyB,WAAWiC,OAAOF,IAAI;IAC5B,MAAMa,aAAa,GAAGjB,YAAY,CAAC,EAAED,YAAY;IACjD,MAAMmB,qBACJ,KAAChE;QAAayB,MAAMqB;kBAClB,cAAA,MAACzD;YACC4E,WAAU;YACVC,SAAS;YACTC,WAAU;YACVC,IAAI;gBAAEC,YAAY;gBAAUC,SAAS;YAAc;;8BAEnD,KAAC5F;oBAAQ6F,MAAM9F,eAAe8F,IAAI;oBAAEC,UAAS;;8BAC7C,KAACC;8BAAK;;;;;IAKZ,IAAIrB,OAAOtC,MAAM,KAAK,WACpB,qBAAO,KAACb;QAAgBqC,OAAM;;IAChC,IAAIc,OAAOtC,MAAM,KAAK,WAAWsC,OAAOtC,MAAM,KAAK,WAAW;QAC5D,qBAAO,KAACZ;YAAoBY,QAAQsC,OAAOtC,MAAM;YAAE4D,MAAK;;IAC1D;IACA,IAAI,CAACvD,UAAU;QACb,qBACE,MAAC9B;YAAM6E,SAAS;;gBACbF;8BACD,KAACjF;oBAAK4F,SAAQ;8BACZ,cAAA,KAAClF;wBAAoB6C,OAAM;;;;;IAInC;IAEA,MAAMvB,WACJ4B,kCAAAA,MAAM9B,SAAS,CAACA,SAAS,CAACG,IAAI,CAAC,CAACC,QAAUA,MAAMC,EAAE,KAAKC,SAASC,SAAS,aAAzEuB,kCACA;IACF,MAAMiC,eACJjC,MAAM9B,SAAS,CAACC,MAAM,KAAK,UACvBjB,6BAA6BsB,SAASC,SAAS,EAAEL,WACjD;IACN,MAAM8D,cAAc1D,SAASL,MAAM,KAAK,WAAWK,SAASL,MAAM,KAAK;IACvE,MAAMF,WAAWiE,cACbnE,2BAA2B;QACzBS;QACAN,WAAW8B,MAAM9B,SAAS;QAC1BgB,UAAUc,MAAMd,QAAQ;QACxBH,OAAO;YACLE,OAAOmC;YACPlD,WAAW8B,MAAMmC,aAAa;YAC9BhD,YAAYa,MAAMoC,cAAc;QAClC;IACF,KACA,EAAE;IACN,0EAA0E;IAC1E,yDAAyD;IACzD,MAAMC,YACJ7D,SAASL,MAAM,KAAK,YACpB8D,iBAAiB,UACjBA,iBAAiB;IACnB,MAAMK,MAAM,OAAOC;QACjB1B,QAAQ;QACRE,WAAW;QACX,IAAI;YACF,MAAMyB,SAAS,MAAMpC,IAAIqC,iBAAiB,CAACjE,SAASD,EAAE,EAAEgE;YACxDjC,gBACEiC,WAAW,aAAaC,OAAOE,kBAAkB,GAC7C,GAAGjD,QAAQK,OAAO,CAACF,IAAI,CAAC,CAAC,EAAE4C,OAAOE,kBAAkB,CAAC,CAAC,EAAEF,OAAOE,kBAAkB,KAAK,IAAI,eAAe,cAAc,SAAS,CAAC,GACjIjD,OAAO,CAAC8C,OAAO,CAAC3C,IAAI,EACxB;gBAAEoC,SAAS;YAAU;QAEzB,EAAE,OAAOW,OAAO;YACd5B,WAAW;gBACTlC,SAAS,AAAC8D,MAAgB9D,OAAO;gBACjC+D,QACED,iBAAiBhF,qBACbgF,MAAMC,MAAM,CAACC,MAAM,CACjB,CAACnE,QAA0C,UAAUA,SAEvD,EAAE;YACV;QACF,SAAU;YACRmC,QAAQ;QACV;IACF;IACA,MAAMiC,SAAS;QACbjC,QAAQ;QACRE,WAAW;QACX,IAAI;YACF,MAAMX,IAAI2C,cAAc,CAACvE,SAASD,EAAE;YACpC+B,gBAAgB,qBAAqB;gBAAE0B,SAAS;YAAU;YAC1D3B,SAASF;QACX,EAAE,OAAOwC,OAAO;YACd5B,WAAW;gBAAElC,SAAS,AAAC8D,MAAgB9D,OAAO;gBAAE+D,QAAQ,EAAE;YAAC;YAC3D/B,QAAQ;QACV;IACF;IAEA,MAAMmC,6BACJ,KAAC7G;QACC6F,SAAQ;QACRiB,yBACE,KAAClH;YAAQ6F,MAAM/F,8BAA8B+F,IAAI;YAAEC,UAAS;;QAE9DqB,UAAU,CAACb;QACXc,SAAS,IAAMhC,aAAa;kBAC7B;;IAKH,qBACE,MAACzE;QAAM6E,SAAS;;YACbF;0BACD,MAAC3E;gBACC4E,WAAW;oBAAE8B,IAAI;oBAAUC,IAAI;gBAAM;gBACrC9B,SAAS;gBACTE,IAAI;oBAAEC,YAAY;wBAAE2B,IAAI;oBAAS;oBAAGC,gBAAgB;gBAAgB;;kCAEpE,MAAC5G;wBACC4E,WAAU;wBACVC,SAAS;wBACTE,IAAI;4BAAEC,YAAY;4BAAU6B,UAAU;wBAAE;;0CAExC,KAAC1G;gCACCmF,SAAQ;gCACRR,WAAU;gCACVC,IAAI;oCAAE+B,WAAW;gCAAa;0CAE7BhF,SAASiF,IAAI;;0CAEhB,KAACjG;gCAA2BW,QAAQK,SAASL,MAAM;;;;kCAErD,MAACzB;wBAAM4E,WAAU;wBAAMC,SAAS;wBAAGE,IAAI;4BAAEiC,UAAU;4BAAQC,QAAQ;wBAAE;;4BAClEzB,4BACC,KAAC/F;gCACC6F,SAAQ;gCACRkB,UAAUtC,QAAQ3C,SAAS2F,MAAM,GAAG;gCACpCT,SAAS,IAAM,KAAKb,IAAI;0CAEvB7C,QAAQC,QAAQ,CAACC,KAAK;iCAEvB;4BACHnB,SAASL,MAAM,KAAK,yBACnB,KAAChC;gCACC6F,SAAQ;gCACRkB,UAAUtC;gCACVuC,SAAS,IAAM,KAAKb,IAAI;0CAEvB7C,QAAQI,KAAK,CAACF,KAAK;iCAEpB;4BACHnB,SAASL,MAAM,KAAK,2BACnB,KAAChC;gCACC6F,SAAQ;gCACR6B,OAAM;gCACNX,UAAUtC;gCACVuC,SAAS,IAAMlC,cAAc;0CAE5BxB,QAAQK,OAAO,CAACH,KAAK;iCAEtB;4BACHnB,SAASL,MAAM,KAAK,wBACnB,KAAChC;gCACC6F,SAAQ;gCACR6B,OAAM;gCACNX,UAAUtC;gCACVuC,SAAS,IAAMlC,cAAc;0CAC9B;iCAGC;4BACHzC,SAASL,MAAM,KAAK,WAAW6E,eAAe;;;;;YAIlDlC,wBACC,KAAC5E;gBAAM4H,UAAS;gBAAQC,SAAS,IAAMhD,WAAW;0BAChD,cAAA,MAACrE;oBAAM6E,SAAS;;sCACd,KAACO;sCAAMhB,QAAQjC,OAAO;;wBACrBiC,QAAQ8B,MAAM,CAACgB,MAAM,GAAG,kBACvB,KAAClH;4BAAM8E,WAAU;4BAAKD,SAAS;4BAAME,IAAI;gCAAEuC,GAAG;gCAAGC,IAAI;4BAAI;sCACtDnD,QAAQ8B,MAAM,CAACsB,KAAK,CAAC,GAAGC,GAAG,CAAC,CAACzF,sBAC5B,KAAC0F;8CAAwC1F,MAAMG,OAAO;mCAA7C,GAAGH,MAAMkD,IAAI,CAAC,CAAC,EAAElD,MAAME,IAAI,EAAE;6BAGxC;;;iBAGN;YACHX,SAAS2F,MAAM,iBACd,KAAC1H;gBAAM4H,UAAS;gBAAUO,eAAY;0BACpC,cAAA,MAAC3H;oBAAM6E,SAAS;;sCACd,KAACO;sCACEtD,SAASL,MAAM,KAAK,UACjB,gEACA;;sCAEN,KAACzB;4BAAM8E,WAAU;4BAAKD,SAAS;4BAAME,IAAI;gCAAEuC,GAAG;gCAAGC,IAAI;4BAAI;sCACtDhG,SAASkG,GAAG,CAAC,CAACG,wBACb,MAACF;;wCACEE,QAAQzF,OAAO;wCAAE;sDAClB,KAACxB;4CAAayB,MAAMwF,QAAQxF,IAAI;sDAAGwF,QAAQtF,SAAS;;;mCAF7CsF,QAAQzF,OAAO;;;;iBAQ9BL,SAASL,MAAM,KAAK,wBACtB,KAACjC;gBAAM4H,UAAS;0BAAO;iBAGrB;YACHtF,SAASL,MAAM,KAAK,YAAY8D,iBAAiB,0BAChD,MAAC/F;gBAAM4H,UAAS;;oBACb1E,WAAW,CAAC6C,aAAa;oBAAE;kCAC5B,KAAC5E;wBAAayB,MAAMkB,MAAMmC,aAAa;kCAAE;;;iBAEzC;0BAEJ,MAACvF;gBACC2H,OAAOvE,MAAMW,GAAG;gBAChB6D,UAAU,CAACC,QAAQC,OACjBrE,SAASqE,SAAS,UAAUtD,aAAa,GAAGA,WAAW,YAAY,CAAC;gBAEtEuD,cAAW;;kCAEX,KAAChI;wBAAI4H,OAAM;wBAAQ5E,OAAM;;kCACzB,KAAChD;wBAAI4H,OAAM;wBAAc5E,OAAM;;;;YAGhCK,MAAMW,GAAG,KAAK,wBACb,KAACjD;gBACCuC,OAAOA;gBACP2E,UAAU5E,MAAM4E,QAAQ;gBACxBpG,UAAUA;gBACVU,UAAUc,MAAMd,QAAQ;gBACxBhB,WAAW8B,MAAM9B,SAAS;gBAC1BiE,eAAenC,MAAMmC,aAAa;gBAClC0C,SAAS,IAAMC;+BAGjB,KAAC1H;gBACCsD,aAAaA;gBACbzB,OAAOT,SAASS,KAAK;gBACrB8F,QAAQ,UAAE3G,2BAAAA,QAAS4G,QAAQ,mBAAI;gBAC/B5E,KAAKA;gBACL6E,cAAczG,SAASL,MAAM,KAAK,WAAW6E,eAAe8B;;0BAIhE,KAAC3H;gBACC+H,MAAMhE;gBACN6C,SAAS,IAAM5C,aAAa;gBAC5BlB,OAAOA;gBACPzB,UAAUA;gBACV2G,gBACE3G,SAAS4G,MAAM,GACXxJ,qBAAoBoE,aAAAA,MAAMqF,GAAG,YAATrF,aAAa,MAAMxB,SAAS4G,MAAM,EAAEE,OAAO,GAC/D;gBAENC,GAAG,WAAE/E,wBAAAA,KAAM+E,GAAG,oBAAI;gBAClBnF,KAAKA;;0BAGP,MAAC/D;gBACC6I,MAAMM,QAAQxE;gBACd+C,SAAS,IAAM9C,cAAc;gBAC7BwE,SAAS;gBACTC,UAAS;;kCAET,KAACjJ;kCACEuE,eAAe,WACZ,uBACA;;kCAEN,KAACzE;kCACC,cAAA,KAACC;sCACEwE,eAAe,WACZ,4DACA;;;kCAGR,MAAC1E;;0CACC,KAACH;gCAAOgH,SAAS,IAAMlC,cAAc;0CAAO;;0CAC5C,KAAC9E;gCACC0H,OAAM;gCACN7B,SAAQ;gCACRmB,SAAS;oCACP,MAAMwC,SAAS3E;oCACfC,cAAc;oCACd,IAAI0E,WAAW,UAAU,KAAK7C;yCACzB,KAAKR,IAAI;gCAChB;0CAECtB,eAAe,WAAW,WAAW;;;;;;;;AAMlD;AACAjB,uBAAuB6F,WAAW,GAAG;AAErC,eAAe7F,uBAAsB"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { type ConsolePluginOrgMount } from '@aglyn/aglyn';
|
|
2
|
+
import { type OutreachSequence } from '../model/outreach.types';
|
|
3
|
+
import type { OutreachMailboxesResult } from './use-outreach-mailboxes';
|
|
4
|
+
import type { OutreachSettingsLoad } from './use-outreach-settings';
|
|
5
|
+
export interface OutreachSequenceEditorProps {
|
|
6
|
+
orgId: string;
|
|
7
|
+
orgMount?: ConsolePluginOrgMount;
|
|
8
|
+
/** The stored sequence, or `null` for a new one. */
|
|
9
|
+
sequence: OutreachSequence | null;
|
|
10
|
+
/** The organization's compliance settings: its countries, and the preview's footer. */
|
|
11
|
+
settings: OutreachSettingsLoad;
|
|
12
|
+
/**
|
|
13
|
+
* The organization's mailboxes, from the Mailboxes section's listener:
|
|
14
|
+
* what the picker offers, and who the preview's emails are from.
|
|
15
|
+
*/
|
|
16
|
+
mailboxes: OutreachMailboxesResult;
|
|
17
|
+
/** The Mailboxes section, where the picker sends a member to connect one. */
|
|
18
|
+
mailboxesPath: string;
|
|
19
|
+
onSaved(sequence: OutreachSequence): void;
|
|
20
|
+
onCancel?(): void;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* The sequence editor (AGL-2980): the name, the site and mailbox, the steps,
|
|
24
|
+
* who it sends to and when, beside a live preview of each email.
|
|
25
|
+
*
|
|
26
|
+
* Every issue the engine's validator finds is shown beside its field — the
|
|
27
|
+
* same validator the save route refuses with — errors once a save was
|
|
28
|
+
* attempted, warnings as soon as they appear. What only the server can
|
|
29
|
+
* judge (whose mailbox, which countries the organization allows, what may
|
|
30
|
+
* no longer change once people are enrolled) comes back from the save and
|
|
31
|
+
* is shown in the same places.
|
|
32
|
+
*/
|
|
33
|
+
export declare function OutreachSequenceEditor(props: OutreachSequenceEditorProps): import("react").JSX.Element;
|
|
34
|
+
export declare namespace OutreachSequenceEditor {
|
|
35
|
+
var displayName: string;
|
|
36
|
+
}
|
|
37
|
+
export default OutreachSequenceEditor;
|