@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,171 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2026 Aglyn LLC
|
|
4
|
+
*
|
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
* you may not use this file except in compliance with the License.
|
|
7
|
+
* You may obtain a copy of the License at
|
|
8
|
+
*
|
|
9
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
*
|
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
* See the License for the specific language governing permissions and
|
|
15
|
+
* limitations under the License.
|
|
16
|
+
*/ 'use client';
|
|
17
|
+
import { _ as _extends } from "@swc/helpers/_/_extends";
|
|
18
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
19
|
+
import { Alert, Button, Chip, CircularProgress, Link, Stack, Typography } from "@mui/material";
|
|
20
|
+
import { useRouter } from "next/navigation";
|
|
21
|
+
/**
|
|
22
|
+
* The pieces every Outreach page shares (AGL-2980): the words for each
|
|
23
|
+
* status, the states a read can be in, and a link that navigates inside the
|
|
24
|
+
* console without reloading it.
|
|
25
|
+
*/ export const OUTREACH_SEQUENCE_STATUS_LABELS = {
|
|
26
|
+
draft: 'Draft',
|
|
27
|
+
active: 'Active',
|
|
28
|
+
paused: 'Paused',
|
|
29
|
+
archived: 'Archived'
|
|
30
|
+
};
|
|
31
|
+
const SEQUENCE_STATUS_COLORS = {
|
|
32
|
+
draft: 'default',
|
|
33
|
+
active: 'success',
|
|
34
|
+
paused: 'warning',
|
|
35
|
+
archived: 'default'
|
|
36
|
+
};
|
|
37
|
+
export const OUTREACH_ENROLLMENT_STATUS_LABELS = {
|
|
38
|
+
active: 'Active',
|
|
39
|
+
paused: 'Paused',
|
|
40
|
+
finished: 'Finished',
|
|
41
|
+
replied: 'Replied',
|
|
42
|
+
bounced: 'Bounced',
|
|
43
|
+
opted_out: 'Opted out',
|
|
44
|
+
stopped: 'Stopped',
|
|
45
|
+
failed: 'Failed'
|
|
46
|
+
};
|
|
47
|
+
const ENROLLMENT_STATUS_COLORS = {
|
|
48
|
+
active: 'success',
|
|
49
|
+
paused: 'warning',
|
|
50
|
+
finished: 'default',
|
|
51
|
+
replied: 'info',
|
|
52
|
+
bounced: 'error',
|
|
53
|
+
opted_out: 'default',
|
|
54
|
+
stopped: 'default',
|
|
55
|
+
failed: 'error'
|
|
56
|
+
};
|
|
57
|
+
/** Why an enrollment is not active, as the table says it. */ export const OUTREACH_STOP_REASON_LABELS = {
|
|
58
|
+
reply: 'They replied',
|
|
59
|
+
hard_bounce: 'The address bounced',
|
|
60
|
+
opt_out_reply: 'They asked not to be emailed',
|
|
61
|
+
unsubscribe: 'They unsubscribed',
|
|
62
|
+
do_not_contact: 'On the do-not-contact list',
|
|
63
|
+
gate: 'No longer eligible',
|
|
64
|
+
manual: 'By a member',
|
|
65
|
+
sequence_archived: 'The sequence was archived',
|
|
66
|
+
send_failed: "An email couldn't be sent"
|
|
67
|
+
};
|
|
68
|
+
export function OutreachSequenceStatusChip(props) {
|
|
69
|
+
return /*#__PURE__*/ _jsx(Chip, {
|
|
70
|
+
size: "small",
|
|
71
|
+
label: OUTREACH_SEQUENCE_STATUS_LABELS[props.status],
|
|
72
|
+
color: SEQUENCE_STATUS_COLORS[props.status],
|
|
73
|
+
variant: props.status === 'archived' ? 'outlined' : 'filled'
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
export function OutreachEnrollmentStatusChip(props) {
|
|
77
|
+
return /*#__PURE__*/ _jsx(Chip, {
|
|
78
|
+
size: "small",
|
|
79
|
+
label: OUTREACH_ENROLLMENT_STATUS_LABELS[props.status],
|
|
80
|
+
color: ENROLLMENT_STATUS_COLORS[props.status]
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
/** Progress for a read still on its way. */ export function OutreachLoading(props) {
|
|
84
|
+
return /*#__PURE__*/ _jsxs(Stack, {
|
|
85
|
+
direction: "row",
|
|
86
|
+
spacing: 1,
|
|
87
|
+
sx: {
|
|
88
|
+
alignItems: 'center',
|
|
89
|
+
py: 2
|
|
90
|
+
},
|
|
91
|
+
role: "status",
|
|
92
|
+
children: [
|
|
93
|
+
/*#__PURE__*/ _jsx(CircularProgress, {
|
|
94
|
+
size: 18
|
|
95
|
+
}),
|
|
96
|
+
/*#__PURE__*/ _jsx(Typography, {
|
|
97
|
+
variant: "body2",
|
|
98
|
+
color: "text.secondary",
|
|
99
|
+
children: props.label
|
|
100
|
+
})
|
|
101
|
+
]
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
/** The words a refused read shows when the route gave none of its own. */ export const OUTREACH_REFUSED_MESSAGE = "You don't have access to this in Sequences. Ask an organization owner or admin for the Use Sequences permission.";
|
|
105
|
+
/**
|
|
106
|
+
* What a failed or refused read shows. A refusal is a statement about the
|
|
107
|
+
* reader, not a fault, so it reads as information and offers no retry.
|
|
108
|
+
*/ export function OutreachLoadProblem(props) {
|
|
109
|
+
if (props.status === 'refused') {
|
|
110
|
+
return /*#__PURE__*/ _jsx(Alert, {
|
|
111
|
+
severity: "info",
|
|
112
|
+
children: props.message || OUTREACH_REFUSED_MESSAGE
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
return /*#__PURE__*/ _jsx(Alert, {
|
|
116
|
+
severity: "error",
|
|
117
|
+
action: props.onRetry ? /*#__PURE__*/ _jsx(Button, {
|
|
118
|
+
color: "inherit",
|
|
119
|
+
size: "small",
|
|
120
|
+
onClick: props.onRetry,
|
|
121
|
+
children: "Try again"
|
|
122
|
+
}) : undefined,
|
|
123
|
+
children: props.message || `The ${props.what} could not be loaded. Reload the page to try again.`
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
/** Navigation inside the console, without reloading it. */ export function useOutreachNavigate() {
|
|
127
|
+
const router = useRouter();
|
|
128
|
+
return (href)=>router.push(href);
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* A link inside the console: a real anchor, so it opens in a new tab when
|
|
132
|
+
* asked to, and a client navigation otherwise.
|
|
133
|
+
*/ export function OutreachLink(props) {
|
|
134
|
+
var _props_underline;
|
|
135
|
+
const navigate = useOutreachNavigate();
|
|
136
|
+
const onClick = (event)=>{
|
|
137
|
+
if (event.defaultPrevented || event.button !== 0 || event.metaKey || event.ctrlKey || event.shiftKey || event.altKey) {
|
|
138
|
+
return;
|
|
139
|
+
}
|
|
140
|
+
event.preventDefault();
|
|
141
|
+
navigate(props.href);
|
|
142
|
+
};
|
|
143
|
+
return /*#__PURE__*/ _jsx(Link, {
|
|
144
|
+
href: props.href,
|
|
145
|
+
onClick: onClick,
|
|
146
|
+
underline: (_props_underline = props.underline) != null ? _props_underline : 'hover',
|
|
147
|
+
children: props.children
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* A moment as a reader in `timeZone` reads it — "Sep 22, 9:14 AM CDT" — or
|
|
152
|
+
* in the reader's own zone when none is known.
|
|
153
|
+
*/ export function formatOutreachTime(ms, timeZone) {
|
|
154
|
+
if (typeof ms !== 'number' || !Number.isFinite(ms)) return '—';
|
|
155
|
+
const options = {
|
|
156
|
+
month: 'short',
|
|
157
|
+
day: 'numeric',
|
|
158
|
+
hour: 'numeric',
|
|
159
|
+
minute: '2-digit',
|
|
160
|
+
timeZoneName: 'short'
|
|
161
|
+
};
|
|
162
|
+
try {
|
|
163
|
+
return new Intl.DateTimeFormat('en-US', _extends({}, options, timeZone ? {
|
|
164
|
+
timeZone
|
|
165
|
+
} : {})).format(ms);
|
|
166
|
+
} catch (unused) {
|
|
167
|
+
return new Intl.DateTimeFormat('en-US', options).format(ms);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
//# sourceMappingURL=outreach-ui.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../../../libs/plugins/outreach/src/lib/components/outreach-ui.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 {\n Alert,\n Button,\n Chip,\n type ChipProps,\n CircularProgress,\n Link,\n Stack,\n Typography,\n} from '@mui/material'\nimport { useRouter } from 'next/navigation'\nimport type { MouseEvent, ReactNode } from 'react'\nimport type {\n OutreachEnrollmentStatus,\n OutreachSequenceStatus,\n OutreachStopReason,\n} from '../model/outreach.types'\nimport type { OutreachLoadStatus } from './use-outreach-data'\n\n/**\n * The pieces every Outreach page shares (AGL-2980): the words for each\n * status, the states a read can be in, and a link that navigates inside the\n * console without reloading it.\n */\n\nexport const OUTREACH_SEQUENCE_STATUS_LABELS: Record<\n OutreachSequenceStatus,\n string\n> = {\n draft: 'Draft',\n active: 'Active',\n paused: 'Paused',\n archived: 'Archived',\n}\n\nconst SEQUENCE_STATUS_COLORS: Record<\n OutreachSequenceStatus,\n ChipProps['color']\n> = {\n draft: 'default',\n active: 'success',\n paused: 'warning',\n archived: 'default',\n}\n\nexport const OUTREACH_ENROLLMENT_STATUS_LABELS: Record<\n OutreachEnrollmentStatus,\n string\n> = {\n active: 'Active',\n paused: 'Paused',\n finished: 'Finished',\n replied: 'Replied',\n bounced: 'Bounced',\n opted_out: 'Opted out',\n stopped: 'Stopped',\n failed: 'Failed',\n}\n\nconst ENROLLMENT_STATUS_COLORS: Record<\n OutreachEnrollmentStatus,\n ChipProps['color']\n> = {\n active: 'success',\n paused: 'warning',\n finished: 'default',\n replied: 'info',\n bounced: 'error',\n opted_out: 'default',\n stopped: 'default',\n failed: 'error',\n}\n\n/** Why an enrollment is not active, as the table says it. */\nexport const OUTREACH_STOP_REASON_LABELS: Record<OutreachStopReason, string> = {\n reply: 'They replied',\n hard_bounce: 'The address bounced',\n opt_out_reply: 'They asked not to be emailed',\n unsubscribe: 'They unsubscribed',\n do_not_contact: 'On the do-not-contact list',\n gate: 'No longer eligible',\n manual: 'By a member',\n sequence_archived: 'The sequence was archived',\n send_failed: \"An email couldn't be sent\",\n}\n\nexport function OutreachSequenceStatusChip(props: {\n status: OutreachSequenceStatus\n}) {\n return (\n <Chip\n size=\"small\"\n label={OUTREACH_SEQUENCE_STATUS_LABELS[props.status]}\n color={SEQUENCE_STATUS_COLORS[props.status]}\n variant={props.status === 'archived' ? 'outlined' : 'filled'}\n />\n )\n}\n\nexport function OutreachEnrollmentStatusChip(props: {\n status: OutreachEnrollmentStatus\n}) {\n return (\n <Chip\n size=\"small\"\n label={OUTREACH_ENROLLMENT_STATUS_LABELS[props.status]}\n color={ENROLLMENT_STATUS_COLORS[props.status]}\n />\n )\n}\n\n/** Progress for a read still on its way. */\nexport function OutreachLoading(props: { label: string }) {\n return (\n <Stack\n direction=\"row\"\n spacing={1}\n sx={{ alignItems: 'center', py: 2 }}\n role=\"status\"\n >\n <CircularProgress size={18} />\n <Typography variant=\"body2\" color=\"text.secondary\">\n {props.label}\n </Typography>\n </Stack>\n )\n}\n\n/** The words a refused read shows when the route gave none of its own. */\nexport const OUTREACH_REFUSED_MESSAGE =\n \"You don't have access to this in Sequences. Ask an organization owner or admin for the Use Sequences permission.\"\n\n/**\n * What a failed or refused read shows. A refusal is a statement about the\n * reader, not a fault, so it reads as information and offers no retry.\n */\nexport function OutreachLoadProblem(props: {\n status: Extract<OutreachLoadStatus, 'error' | 'refused'>\n /** What could not be read, for the error sentence. */\n what: string\n message?: string | null\n onRetry?: () => void\n}) {\n if (props.status === 'refused') {\n return (\n <Alert severity=\"info\">{props.message || OUTREACH_REFUSED_MESSAGE}</Alert>\n )\n }\n return (\n <Alert\n severity=\"error\"\n action={\n props.onRetry ? (\n <Button color=\"inherit\" size=\"small\" onClick={props.onRetry}>\n Try again\n </Button>\n ) : undefined\n }\n >\n {props.message ||\n `The ${props.what} could not be loaded. Reload the page to try again.`}\n </Alert>\n )\n}\n\n/** Navigation inside the console, without reloading it. */\nexport function useOutreachNavigate(): (href: string) => void {\n const router = useRouter()\n return (href: string) => router.push(href)\n}\n\n/**\n * A link inside the console: a real anchor, so it opens in a new tab when\n * asked to, and a client navigation otherwise.\n */\nexport function OutreachLink(props: {\n href: string\n children: ReactNode\n underline?: 'hover' | 'always' | 'none'\n}) {\n const navigate = useOutreachNavigate()\n const onClick = (event: MouseEvent<HTMLAnchorElement>) => {\n if (\n event.defaultPrevented ||\n event.button !== 0 ||\n event.metaKey ||\n event.ctrlKey ||\n event.shiftKey ||\n event.altKey\n ) {\n return\n }\n event.preventDefault()\n navigate(props.href)\n }\n return (\n <Link\n href={props.href}\n onClick={onClick}\n underline={props.underline ?? 'hover'}\n >\n {props.children}\n </Link>\n )\n}\n\n/**\n * A moment as a reader in `timeZone` reads it — \"Sep 22, 9:14 AM CDT\" — or\n * in the reader's own zone when none is known.\n */\nexport function formatOutreachTime(\n ms: number | null | undefined,\n timeZone?: string | null,\n): string {\n if (typeof ms !== 'number' || !Number.isFinite(ms)) return '—'\n const options: Intl.DateTimeFormatOptions = {\n month: 'short',\n day: 'numeric',\n hour: 'numeric',\n minute: '2-digit',\n timeZoneName: 'short',\n }\n try {\n return new Intl.DateTimeFormat('en-US', {\n ...options,\n ...(timeZone ? { timeZone } : {}),\n }).format(ms)\n } catch {\n return new Intl.DateTimeFormat('en-US', options).format(ms)\n }\n}\n"],"names":["Alert","Button","Chip","CircularProgress","Link","Stack","Typography","useRouter","OUTREACH_SEQUENCE_STATUS_LABELS","draft","active","paused","archived","SEQUENCE_STATUS_COLORS","OUTREACH_ENROLLMENT_STATUS_LABELS","finished","replied","bounced","opted_out","stopped","failed","ENROLLMENT_STATUS_COLORS","OUTREACH_STOP_REASON_LABELS","reply","hard_bounce","opt_out_reply","unsubscribe","do_not_contact","gate","manual","sequence_archived","send_failed","OutreachSequenceStatusChip","props","size","label","status","color","variant","OutreachEnrollmentStatusChip","OutreachLoading","direction","spacing","sx","alignItems","py","role","OUTREACH_REFUSED_MESSAGE","OutreachLoadProblem","severity","message","action","onRetry","onClick","undefined","what","useOutreachNavigate","router","href","push","OutreachLink","navigate","event","defaultPrevented","button","metaKey","ctrlKey","shiftKey","altKey","preventDefault","underline","children","formatOutreachTime","ms","timeZone","Number","isFinite","options","month","day","hour","minute","timeZoneName","Intl","DateTimeFormat","format"],"mappings":"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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { OutreachSendWindow } from '../model/outreach.types';
|
|
2
|
+
/** Office hours on weekdays: where an override starts. */
|
|
3
|
+
export declare const OUTREACH_DEFAULT_WINDOW: OutreachSendWindow;
|
|
4
|
+
/** `540` → `"09:00"`, the value a time input takes. */
|
|
5
|
+
export declare function minutesToClock(minutes: number): string;
|
|
6
|
+
/** `"09:00"` → `540`; `NaN` for anything else, so the validator names it. */
|
|
7
|
+
export declare function clockToMinutes(value: string): number;
|
|
8
|
+
export interface OutreachSendWindowFieldsProps {
|
|
9
|
+
/** The sequence's own hours, or `null` to send in its mailbox's. */
|
|
10
|
+
window: OutreachSendWindow | null;
|
|
11
|
+
onChange(window: OutreachSendWindow | null): void;
|
|
12
|
+
/** The issue to show under the days, and under the hours. */
|
|
13
|
+
daysIssue?: string;
|
|
14
|
+
hoursIssue?: string;
|
|
15
|
+
disabled?: boolean;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* A sequence's sending hours (AGL-2980): its mailbox's by default, or days
|
|
19
|
+
* and hours of its own, read in the mailbox's timezone either way.
|
|
20
|
+
*/
|
|
21
|
+
export declare function OutreachSendWindowFields(props: OutreachSendWindowFieldsProps): import("react").JSX.Element;
|
|
22
|
+
export declare namespace OutreachSendWindowFields {
|
|
23
|
+
var displayName: string;
|
|
24
|
+
}
|
|
25
|
+
export default OutreachSendWindowFields;
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2026 Aglyn LLC
|
|
4
|
+
*
|
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
* you may not use this file except in compliance with the License.
|
|
7
|
+
* You may obtain a copy of the License at
|
|
8
|
+
*
|
|
9
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
*
|
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
* See the License for the specific language governing permissions and
|
|
15
|
+
* limitations under the License.
|
|
16
|
+
*/ 'use client';
|
|
17
|
+
import { _ as _extends } from "@swc/helpers/_/_extends";
|
|
18
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
19
|
+
import { FormControlLabel, FormHelperText, Stack, Switch, TextField, ToggleButton, ToggleButtonGroup, Typography } from "@mui/material";
|
|
20
|
+
/** Weekdays in the order a week reads, as `OutreachSendWindow.days` numbers them. */ const DAYS = [
|
|
21
|
+
[
|
|
22
|
+
1,
|
|
23
|
+
'Mon',
|
|
24
|
+
'Monday'
|
|
25
|
+
],
|
|
26
|
+
[
|
|
27
|
+
2,
|
|
28
|
+
'Tue',
|
|
29
|
+
'Tuesday'
|
|
30
|
+
],
|
|
31
|
+
[
|
|
32
|
+
3,
|
|
33
|
+
'Wed',
|
|
34
|
+
'Wednesday'
|
|
35
|
+
],
|
|
36
|
+
[
|
|
37
|
+
4,
|
|
38
|
+
'Thu',
|
|
39
|
+
'Thursday'
|
|
40
|
+
],
|
|
41
|
+
[
|
|
42
|
+
5,
|
|
43
|
+
'Fri',
|
|
44
|
+
'Friday'
|
|
45
|
+
],
|
|
46
|
+
[
|
|
47
|
+
6,
|
|
48
|
+
'Sat',
|
|
49
|
+
'Saturday'
|
|
50
|
+
],
|
|
51
|
+
[
|
|
52
|
+
0,
|
|
53
|
+
'Sun',
|
|
54
|
+
'Sunday'
|
|
55
|
+
]
|
|
56
|
+
];
|
|
57
|
+
/** Office hours on weekdays: where an override starts. */ export const OUTREACH_DEFAULT_WINDOW = {
|
|
58
|
+
days: [
|
|
59
|
+
1,
|
|
60
|
+
2,
|
|
61
|
+
3,
|
|
62
|
+
4,
|
|
63
|
+
5
|
|
64
|
+
],
|
|
65
|
+
startMinute: 9 * 60,
|
|
66
|
+
endMinute: 17 * 60
|
|
67
|
+
};
|
|
68
|
+
/** `540` → `"09:00"`, the value a time input takes. */ export function minutesToClock(minutes) {
|
|
69
|
+
if (!Number.isInteger(minutes) || minutes < 0) return '';
|
|
70
|
+
const bounded = Math.min(minutes, 24 * 60 - 1);
|
|
71
|
+
return `${String(Math.floor(bounded / 60)).padStart(2, '0')}:${String(bounded % 60).padStart(2, '0')}`;
|
|
72
|
+
}
|
|
73
|
+
/** `"09:00"` → `540`; `NaN` for anything else, so the validator names it. */ export function clockToMinutes(value) {
|
|
74
|
+
const match = /^(\d{1,2}):(\d{2})$/.exec(value.trim());
|
|
75
|
+
if (!match) return Number.NaN;
|
|
76
|
+
const minutes = Number(match[1]) * 60 + Number(match[2]);
|
|
77
|
+
return Number(match[1]) < 24 && Number(match[2]) < 60 ? minutes : Number.NaN;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* A sequence's sending hours (AGL-2980): its mailbox's by default, or days
|
|
81
|
+
* and hours of its own, read in the mailbox's timezone either way.
|
|
82
|
+
*/ export function OutreachSendWindowFields(props) {
|
|
83
|
+
const { window, disabled } = props;
|
|
84
|
+
return /*#__PURE__*/ _jsxs(Stack, {
|
|
85
|
+
spacing: 1.5,
|
|
86
|
+
children: [
|
|
87
|
+
/*#__PURE__*/ _jsx(FormControlLabel, {
|
|
88
|
+
control: /*#__PURE__*/ _jsx(Switch, {
|
|
89
|
+
checked: window !== null,
|
|
90
|
+
onChange: (event)=>props.onChange(event.target.checked ? _extends({}, OUTREACH_DEFAULT_WINDOW) : null),
|
|
91
|
+
disabled: disabled
|
|
92
|
+
}),
|
|
93
|
+
label: "Sending hours of its own"
|
|
94
|
+
}),
|
|
95
|
+
window === null ? /*#__PURE__*/ _jsx(Typography, {
|
|
96
|
+
variant: "body2",
|
|
97
|
+
color: "text.secondary",
|
|
98
|
+
children: "Sends in its mailbox’s sending hours."
|
|
99
|
+
}) : /*#__PURE__*/ _jsxs(Stack, {
|
|
100
|
+
spacing: 1.5,
|
|
101
|
+
children: [
|
|
102
|
+
/*#__PURE__*/ _jsxs(Stack, {
|
|
103
|
+
spacing: 0.5,
|
|
104
|
+
children: [
|
|
105
|
+
/*#__PURE__*/ _jsx(ToggleButtonGroup, {
|
|
106
|
+
value: window.days,
|
|
107
|
+
onChange: (_event, days)=>props.onChange(_extends({}, window, {
|
|
108
|
+
days: [
|
|
109
|
+
...days
|
|
110
|
+
].sort()
|
|
111
|
+
})),
|
|
112
|
+
"aria-label": "Days it sends on",
|
|
113
|
+
size: "small",
|
|
114
|
+
disabled: disabled,
|
|
115
|
+
sx: {
|
|
116
|
+
flexWrap: 'wrap'
|
|
117
|
+
},
|
|
118
|
+
children: DAYS.map(([day, short, long])=>/*#__PURE__*/ _jsx(ToggleButton, {
|
|
119
|
+
value: day,
|
|
120
|
+
"aria-label": long,
|
|
121
|
+
children: short
|
|
122
|
+
}, day))
|
|
123
|
+
}),
|
|
124
|
+
props.daysIssue ? /*#__PURE__*/ _jsx(FormHelperText, {
|
|
125
|
+
error: true,
|
|
126
|
+
children: props.daysIssue
|
|
127
|
+
}) : null
|
|
128
|
+
]
|
|
129
|
+
}),
|
|
130
|
+
/*#__PURE__*/ _jsxs(Stack, {
|
|
131
|
+
direction: {
|
|
132
|
+
xs: 'column',
|
|
133
|
+
sm: 'row'
|
|
134
|
+
},
|
|
135
|
+
spacing: 2,
|
|
136
|
+
children: [
|
|
137
|
+
/*#__PURE__*/ _jsx(TextField, {
|
|
138
|
+
type: "time",
|
|
139
|
+
label: "From",
|
|
140
|
+
value: minutesToClock(window.startMinute),
|
|
141
|
+
onChange: (event)=>props.onChange(_extends({}, window, {
|
|
142
|
+
startMinute: clockToMinutes(event.target.value)
|
|
143
|
+
})),
|
|
144
|
+
disabled: disabled,
|
|
145
|
+
error: Boolean(props.hoursIssue),
|
|
146
|
+
slotProps: {
|
|
147
|
+
inputLabel: {
|
|
148
|
+
shrink: true
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
}),
|
|
152
|
+
/*#__PURE__*/ _jsx(TextField, {
|
|
153
|
+
type: "time",
|
|
154
|
+
label: "Until",
|
|
155
|
+
value: minutesToClock(window.endMinute),
|
|
156
|
+
onChange: (event)=>props.onChange(_extends({}, window, {
|
|
157
|
+
endMinute: clockToMinutes(event.target.value)
|
|
158
|
+
})),
|
|
159
|
+
disabled: disabled,
|
|
160
|
+
error: Boolean(props.hoursIssue),
|
|
161
|
+
helperText: props.hoursIssue,
|
|
162
|
+
slotProps: {
|
|
163
|
+
inputLabel: {
|
|
164
|
+
shrink: true
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
})
|
|
168
|
+
]
|
|
169
|
+
})
|
|
170
|
+
]
|
|
171
|
+
})
|
|
172
|
+
]
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
OutreachSendWindowFields.displayName = 'OutreachSendWindowFields';
|
|
176
|
+
export default OutreachSendWindowFields;
|
|
177
|
+
|
|
178
|
+
//# sourceMappingURL=send-window-fields.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../../../libs/plugins/outreach/src/lib/components/send-window-fields.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 {\n FormControlLabel,\n FormHelperText,\n Stack,\n Switch,\n TextField,\n ToggleButton,\n ToggleButtonGroup,\n Typography,\n} from '@mui/material'\nimport type { OutreachSendWindow } from '../model/outreach.types'\n\n/** Weekdays in the order a week reads, as `OutreachSendWindow.days` numbers them. */\nconst DAYS: ReadonlyArray<[number, string, string]> = [\n [1, 'Mon', 'Monday'],\n [2, 'Tue', 'Tuesday'],\n [3, 'Wed', 'Wednesday'],\n [4, 'Thu', 'Thursday'],\n [5, 'Fri', 'Friday'],\n [6, 'Sat', 'Saturday'],\n [0, 'Sun', 'Sunday'],\n]\n\n/** Office hours on weekdays: where an override starts. */\nexport const OUTREACH_DEFAULT_WINDOW: OutreachSendWindow = {\n days: [1, 2, 3, 4, 5],\n startMinute: 9 * 60,\n endMinute: 17 * 60,\n}\n\n/** `540` → `\"09:00\"`, the value a time input takes. */\nexport function minutesToClock(minutes: number): string {\n if (!Number.isInteger(minutes) || minutes < 0) return ''\n const bounded = Math.min(minutes, 24 * 60 - 1)\n return `${String(Math.floor(bounded / 60)).padStart(2, '0')}:${String(bounded % 60).padStart(2, '0')}`\n}\n\n/** `\"09:00\"` → `540`; `NaN` for anything else, so the validator names it. */\nexport function clockToMinutes(value: string): number {\n const match = /^(\\d{1,2}):(\\d{2})$/.exec(value.trim())\n if (!match) return Number.NaN\n const minutes = Number(match[1]) * 60 + Number(match[2])\n return Number(match[1]) < 24 && Number(match[2]) < 60 ? minutes : Number.NaN\n}\n\nexport interface OutreachSendWindowFieldsProps {\n /** The sequence's own hours, or `null` to send in its mailbox's. */\n window: OutreachSendWindow | null\n onChange(window: OutreachSendWindow | null): void\n /** The issue to show under the days, and under the hours. */\n daysIssue?: string\n hoursIssue?: string\n disabled?: boolean\n}\n\n/**\n * A sequence's sending hours (AGL-2980): its mailbox's by default, or days\n * and hours of its own, read in the mailbox's timezone either way.\n */\nexport function OutreachSendWindowFields(props: OutreachSendWindowFieldsProps) {\n const { window, disabled } = props\n return (\n <Stack spacing={1.5}>\n <FormControlLabel\n control={\n <Switch\n checked={window !== null}\n onChange={(event) =>\n props.onChange(\n event.target.checked ? { ...OUTREACH_DEFAULT_WINDOW } : null,\n )\n }\n disabled={disabled}\n />\n }\n label=\"Sending hours of its own\"\n />\n {window === null ? (\n <Typography variant=\"body2\" color=\"text.secondary\">\n Sends in its mailbox’s sending hours.\n </Typography>\n ) : (\n <Stack spacing={1.5}>\n <Stack spacing={0.5}>\n <ToggleButtonGroup\n value={window.days}\n onChange={(_event, days: number[]) =>\n props.onChange({ ...window, days: [...days].sort() })\n }\n aria-label=\"Days it sends on\"\n size=\"small\"\n disabled={disabled}\n sx={{ flexWrap: 'wrap' }}\n >\n {DAYS.map(([day, short, long]) => (\n <ToggleButton key={day} value={day} aria-label={long}>\n {short}\n </ToggleButton>\n ))}\n </ToggleButtonGroup>\n {props.daysIssue ? (\n <FormHelperText error>{props.daysIssue}</FormHelperText>\n ) : null}\n </Stack>\n <Stack direction={{ xs: 'column', sm: 'row' }} spacing={2}>\n <TextField\n type=\"time\"\n label=\"From\"\n value={minutesToClock(window.startMinute)}\n onChange={(event) =>\n props.onChange({\n ...window,\n startMinute: clockToMinutes(event.target.value),\n })\n }\n disabled={disabled}\n error={Boolean(props.hoursIssue)}\n slotProps={{ inputLabel: { shrink: true } }}\n />\n <TextField\n type=\"time\"\n label=\"Until\"\n value={minutesToClock(window.endMinute)}\n onChange={(event) =>\n props.onChange({\n ...window,\n endMinute: clockToMinutes(event.target.value),\n })\n }\n disabled={disabled}\n error={Boolean(props.hoursIssue)}\n helperText={props.hoursIssue}\n slotProps={{ inputLabel: { shrink: true } }}\n />\n </Stack>\n </Stack>\n )}\n </Stack>\n )\n}\nOutreachSendWindowFields.displayName = 'OutreachSendWindowFields'\n\nexport default OutreachSendWindowFields\n"],"names":["FormControlLabel","FormHelperText","Stack","Switch","TextField","ToggleButton","ToggleButtonGroup","Typography","DAYS","OUTREACH_DEFAULT_WINDOW","days","startMinute","endMinute","minutesToClock","minutes","Number","isInteger","bounded","Math","min","String","floor","padStart","clockToMinutes","value","match","exec","trim","NaN","OutreachSendWindowFields","props","window","disabled","spacing","control","checked","onChange","event","target","label","variant","color","_event","sort","aria-label","size","sx","flexWrap","map","day","short","long","daysIssue","error","direction","xs","sm","type","Boolean","hoursIssue","slotProps","inputLabel","shrink","helperText","displayName"],"mappings":"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"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import type { ConsolePluginOrgMount } from '@aglyn/aglyn';
|
|
2
|
+
import type { OutreachMailboxesResult } from './use-outreach-mailboxes';
|
|
3
|
+
import type { OutreachSettingsLoad } from './use-outreach-settings';
|
|
4
|
+
export type OutreachSequenceTab = 'steps' | 'enrollments';
|
|
5
|
+
export interface OutreachSequenceDetailProps {
|
|
6
|
+
orgId: string;
|
|
7
|
+
orgMount?: ConsolePluginOrgMount;
|
|
8
|
+
/** The organization document the shell loaded: whose consent groups name a site's contacts. */
|
|
9
|
+
org?: Record<string, unknown> | null;
|
|
10
|
+
/** Where the Sequences section lives: `/[orgSlug]/outreach/sequences`. */
|
|
11
|
+
sectionPath: string;
|
|
12
|
+
sequenceId: string;
|
|
13
|
+
tab: OutreachSequenceTab;
|
|
14
|
+
settings: OutreachSettingsLoad;
|
|
15
|
+
mailboxes: OutreachMailboxesResult;
|
|
16
|
+
/** The Mailboxes section: where a mailbox is connected, resumed or reconnected. */
|
|
17
|
+
mailboxesPath: string;
|
|
18
|
+
/** The Compliance section: where the footer's legal name and address are set. */
|
|
19
|
+
compliancePath: string;
|
|
20
|
+
}
|
|
21
|
+
/** Something activation would refuse, and where it is put right. */
|
|
22
|
+
export interface OutreachActivationBlocker {
|
|
23
|
+
message: string;
|
|
24
|
+
href: string;
|
|
25
|
+
linkLabel: string;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* What stops a sequence being activated, read before anyone clicks: its
|
|
29
|
+
* mailbox not sending, and a footer the organization cannot write yet —
|
|
30
|
+
* each in the words the status route refuses with. Only a finished read
|
|
31
|
+
* says something is missing, so nothing is claimed while one is loading.
|
|
32
|
+
*/
|
|
33
|
+
export declare function outreachActivationBlockers(input: {
|
|
34
|
+
sequence: {
|
|
35
|
+
mailboxId: string;
|
|
36
|
+
};
|
|
37
|
+
mailboxes: OutreachMailboxesResult;
|
|
38
|
+
settings: OutreachSettingsLoad;
|
|
39
|
+
paths: {
|
|
40
|
+
steps: string;
|
|
41
|
+
mailboxes: string;
|
|
42
|
+
compliance: string;
|
|
43
|
+
};
|
|
44
|
+
}): OutreachActivationBlocker[];
|
|
45
|
+
/**
|
|
46
|
+
* One sequence (AGL-2980): its steps in the editor, the people enrolled in
|
|
47
|
+
* it, and what can be done with it — activate, pause, archive, delete a
|
|
48
|
+
* draft, and enroll people in an active one.
|
|
49
|
+
*/
|
|
50
|
+
export declare function OutreachSequenceDetail(props: OutreachSequenceDetailProps): import("react").JSX.Element;
|
|
51
|
+
export declare namespace OutreachSequenceDetail {
|
|
52
|
+
var displayName: string;
|
|
53
|
+
}
|
|
54
|
+
export default OutreachSequenceDetail;
|