@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,326 @@
|
|
|
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 { mdiArrowDown, mdiArrowUp, mdiCodeBraces, mdiTrashCanOutline } from "@aglyn/shared-data-mdi";
|
|
20
|
+
import { MdiIcon } from "@aglyn/shared-ui-jsx";
|
|
21
|
+
import { Autocomplete, Button, Card, CardContent, FormControlLabel, IconButton, ListSubheader, Menu, MenuItem, Stack, Switch, TextField, Tooltip, Typography } from "@mui/material";
|
|
22
|
+
import { useRef, useState } from "react";
|
|
23
|
+
import { OUTREACH_MERGE_FIELDS } from "../engine/sequence-validation.js";
|
|
24
|
+
import { OUTREACH_MAX_STEP_DELAY_BUSINESS_DAYS, OUTREACH_TASK_KIND_LABELS, OUTREACH_TASK_KINDS } from "../model/outreach.types.js";
|
|
25
|
+
/** The merge fields, grouped the way the picker heads them. */ const FIELD_GROUPS = [
|
|
26
|
+
...new Set(OUTREACH_MERGE_FIELDS.map((field)=>field.group))
|
|
27
|
+
];
|
|
28
|
+
/**
|
|
29
|
+
* One step of the sequence editor (AGL-2980): an email — subject, body or a
|
|
30
|
+
* CRM template, merge fields, the wait before it — or a task for the rep.
|
|
31
|
+
*/ export function OutreachStepCard(props) {
|
|
32
|
+
var _OUTREACH_TASK_KIND_LABELS_step_taskKind, _props_issues_step;
|
|
33
|
+
const { step, index, count, disabled } = props;
|
|
34
|
+
const title = step.kind === 'email' ? `Step ${index + 1} · Email` : `Step ${index + 1} · ${(_OUTREACH_TASK_KIND_LABELS_step_taskKind = OUTREACH_TASK_KIND_LABELS[step.taskKind]) != null ? _OUTREACH_TASK_KIND_LABELS_step_taskKind : 'Task'}`;
|
|
35
|
+
return /*#__PURE__*/ _jsx(Card, {
|
|
36
|
+
variant: "outlined",
|
|
37
|
+
component: "section",
|
|
38
|
+
"aria-label": title,
|
|
39
|
+
children: /*#__PURE__*/ _jsx(CardContent, {
|
|
40
|
+
children: /*#__PURE__*/ _jsxs(Stack, {
|
|
41
|
+
spacing: 2,
|
|
42
|
+
children: [
|
|
43
|
+
/*#__PURE__*/ _jsxs(Stack, {
|
|
44
|
+
direction: "row",
|
|
45
|
+
spacing: 1,
|
|
46
|
+
sx: {
|
|
47
|
+
alignItems: 'center'
|
|
48
|
+
},
|
|
49
|
+
children: [
|
|
50
|
+
/*#__PURE__*/ _jsx(Typography, {
|
|
51
|
+
variant: "subtitle1",
|
|
52
|
+
sx: {
|
|
53
|
+
flexGrow: 1
|
|
54
|
+
},
|
|
55
|
+
children: title
|
|
56
|
+
}),
|
|
57
|
+
/*#__PURE__*/ _jsx(Tooltip, {
|
|
58
|
+
title: "Move up",
|
|
59
|
+
children: /*#__PURE__*/ _jsx("span", {
|
|
60
|
+
children: /*#__PURE__*/ _jsx(IconButton, {
|
|
61
|
+
size: "small",
|
|
62
|
+
"aria-label": `Move step ${index + 1} up`,
|
|
63
|
+
disabled: disabled || index === 0,
|
|
64
|
+
onClick: ()=>props.onMove(-1),
|
|
65
|
+
children: /*#__PURE__*/ _jsx(MdiIcon, {
|
|
66
|
+
path: mdiArrowUp.path,
|
|
67
|
+
fontSize: "small"
|
|
68
|
+
})
|
|
69
|
+
})
|
|
70
|
+
})
|
|
71
|
+
}),
|
|
72
|
+
/*#__PURE__*/ _jsx(Tooltip, {
|
|
73
|
+
title: "Move down",
|
|
74
|
+
children: /*#__PURE__*/ _jsx("span", {
|
|
75
|
+
children: /*#__PURE__*/ _jsx(IconButton, {
|
|
76
|
+
size: "small",
|
|
77
|
+
"aria-label": `Move step ${index + 1} down`,
|
|
78
|
+
disabled: disabled || index === count - 1,
|
|
79
|
+
onClick: ()=>props.onMove(1),
|
|
80
|
+
children: /*#__PURE__*/ _jsx(MdiIcon, {
|
|
81
|
+
path: mdiArrowDown.path,
|
|
82
|
+
fontSize: "small"
|
|
83
|
+
})
|
|
84
|
+
})
|
|
85
|
+
})
|
|
86
|
+
}),
|
|
87
|
+
/*#__PURE__*/ _jsx(Tooltip, {
|
|
88
|
+
title: "Remove",
|
|
89
|
+
children: /*#__PURE__*/ _jsx("span", {
|
|
90
|
+
children: /*#__PURE__*/ _jsx(IconButton, {
|
|
91
|
+
size: "small",
|
|
92
|
+
"aria-label": `Remove step ${index + 1}`,
|
|
93
|
+
disabled: disabled || count === 1,
|
|
94
|
+
onClick: props.onRemove,
|
|
95
|
+
children: /*#__PURE__*/ _jsx(MdiIcon, {
|
|
96
|
+
path: mdiTrashCanOutline.path,
|
|
97
|
+
fontSize: "small"
|
|
98
|
+
})
|
|
99
|
+
})
|
|
100
|
+
})
|
|
101
|
+
})
|
|
102
|
+
]
|
|
103
|
+
}),
|
|
104
|
+
/*#__PURE__*/ _jsx(DelayField, _extends({}, props)),
|
|
105
|
+
step.kind === 'email' ? /*#__PURE__*/ _jsx(EmailStepFields, _extends({}, props, {
|
|
106
|
+
step: step
|
|
107
|
+
})) : step.kind === 'task' ? /*#__PURE__*/ _jsx(TaskStepFields, _extends({}, props, {
|
|
108
|
+
step: step
|
|
109
|
+
})) : /*#__PURE__*/ _jsx(Typography, {
|
|
110
|
+
variant: "body2",
|
|
111
|
+
color: "error",
|
|
112
|
+
children: (_props_issues_step = props.issues['step']) != null ? _props_issues_step : 'A step is an email or a task.'
|
|
113
|
+
})
|
|
114
|
+
]
|
|
115
|
+
})
|
|
116
|
+
})
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
OutreachStepCard.displayName = 'OutreachStepCard';
|
|
120
|
+
function DelayField(props) {
|
|
121
|
+
const { step, index, disabled } = props;
|
|
122
|
+
const first = index === 0;
|
|
123
|
+
const issue = props.issues['delayBusinessDays'];
|
|
124
|
+
return /*#__PURE__*/ _jsx(TextField, {
|
|
125
|
+
type: "number",
|
|
126
|
+
label: first ? 'Wait after enrolling (business days)' : 'Wait after the step before (business days)',
|
|
127
|
+
value: Number.isFinite(step.delayBusinessDays) ? step.delayBusinessDays : '',
|
|
128
|
+
onChange: (event)=>props.onChange(_extends({}, step, {
|
|
129
|
+
delayBusinessDays: event.target.value === '' ? Number.NaN : Number(event.target.value)
|
|
130
|
+
})),
|
|
131
|
+
disabled: disabled,
|
|
132
|
+
error: Boolean(issue),
|
|
133
|
+
helperText: issue != null ? issue : first ? '0 sends at the next opening of the sending hours.' : 'Counted in the mailbox’s timezone, skipping weekends.',
|
|
134
|
+
slotProps: {
|
|
135
|
+
htmlInput: {
|
|
136
|
+
min: 0,
|
|
137
|
+
max: OUTREACH_MAX_STEP_DELAY_BUSINESS_DAYS,
|
|
138
|
+
step: 1
|
|
139
|
+
}
|
|
140
|
+
},
|
|
141
|
+
sx: {
|
|
142
|
+
maxWidth: {
|
|
143
|
+
sm: 360
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
function EmailStepFields(props) {
|
|
149
|
+
var _props_templates_find;
|
|
150
|
+
const { step, disabled, issues } = props;
|
|
151
|
+
const subjectRef = useRef(null);
|
|
152
|
+
const bodyRef = useRef(null);
|
|
153
|
+
const lastFocused = useRef('body');
|
|
154
|
+
const [fieldsAnchor, setFieldsAnchor] = useState(null);
|
|
155
|
+
const template = (_props_templates_find = props.templates.find((option)=>option.id === step.templateId)) != null ? _props_templates_find : null;
|
|
156
|
+
const showSubject = !props.inThread;
|
|
157
|
+
/** Puts `{{key}}` where the caret was in the field last focused. */ const insertField = (key)=>{
|
|
158
|
+
var _ref, _ref1;
|
|
159
|
+
setFieldsAnchor(null);
|
|
160
|
+
const token = `{{${key}}}`;
|
|
161
|
+
const target = lastFocused.current === 'subject' && showSubject ? 'subject' : template ? null : 'body';
|
|
162
|
+
if (!target) return;
|
|
163
|
+
const element = target === 'subject' ? subjectRef.current : bodyRef.current;
|
|
164
|
+
const value = step[target];
|
|
165
|
+
const start = (_ref = element == null ? void 0 : element.selectionStart) != null ? _ref : value.length;
|
|
166
|
+
const end = (_ref1 = element == null ? void 0 : element.selectionEnd) != null ? _ref1 : value.length;
|
|
167
|
+
props.onChange(_extends({}, step, {
|
|
168
|
+
[target]: `${value.slice(0, start)}${token}${value.slice(end)}`
|
|
169
|
+
}));
|
|
170
|
+
requestAnimationFrame(()=>{
|
|
171
|
+
element == null ? void 0 : element.focus();
|
|
172
|
+
element == null ? void 0 : element.setSelectionRange(start + token.length, start + token.length);
|
|
173
|
+
});
|
|
174
|
+
};
|
|
175
|
+
return /*#__PURE__*/ _jsxs(Stack, {
|
|
176
|
+
spacing: 2,
|
|
177
|
+
children: [
|
|
178
|
+
props.firstEmail ? null : /*#__PURE__*/ _jsx(FormControlLabel, {
|
|
179
|
+
control: /*#__PURE__*/ _jsx(Switch, {
|
|
180
|
+
checked: step.replyInThread !== false,
|
|
181
|
+
onChange: (event)=>props.onChange(_extends({}, step, {
|
|
182
|
+
replyInThread: event.target.checked
|
|
183
|
+
})),
|
|
184
|
+
disabled: disabled
|
|
185
|
+
}),
|
|
186
|
+
label: "Reply in the same thread"
|
|
187
|
+
}),
|
|
188
|
+
showSubject ? /*#__PURE__*/ _jsx(TextField, {
|
|
189
|
+
label: "Subject",
|
|
190
|
+
value: step.subject,
|
|
191
|
+
inputRef: subjectRef,
|
|
192
|
+
onFocus: ()=>lastFocused.current = 'subject',
|
|
193
|
+
onChange: (event)=>props.onChange(_extends({}, step, {
|
|
194
|
+
subject: event.target.value
|
|
195
|
+
})),
|
|
196
|
+
disabled: disabled,
|
|
197
|
+
error: Boolean(issues['subject']),
|
|
198
|
+
helperText: issues['subject'],
|
|
199
|
+
fullWidth: true
|
|
200
|
+
}) : /*#__PURE__*/ _jsx(Typography, {
|
|
201
|
+
variant: "body2",
|
|
202
|
+
color: "text.secondary",
|
|
203
|
+
children: props.threadSubject ? `Sent as a reply: “Re: ${props.threadSubject}”.` : 'Sent as a reply in the thread the earlier email started.'
|
|
204
|
+
}),
|
|
205
|
+
/*#__PURE__*/ _jsx(Autocomplete, {
|
|
206
|
+
options: [
|
|
207
|
+
...props.templates
|
|
208
|
+
],
|
|
209
|
+
value: template,
|
|
210
|
+
getOptionLabel: (option)=>option.name,
|
|
211
|
+
isOptionEqualToValue: (option, value)=>option.id === value.id,
|
|
212
|
+
onChange: (_event, next)=>{
|
|
213
|
+
var _ref;
|
|
214
|
+
return props.onChange(_extends({}, step, {
|
|
215
|
+
templateId: (_ref = next == null ? void 0 : next.id) != null ? _ref : null,
|
|
216
|
+
body: next ? '' : step.body
|
|
217
|
+
}));
|
|
218
|
+
},
|
|
219
|
+
disabled: disabled,
|
|
220
|
+
renderInput: (params)=>/*#__PURE__*/ _jsx(TextField, _extends({}, params, {
|
|
221
|
+
label: "CRM email template",
|
|
222
|
+
helperText: template ? 'The template’s body is sent; this step’s own subject is the one used.' : 'Optional. Pick one to send its body instead of writing it here.'
|
|
223
|
+
}))
|
|
224
|
+
}),
|
|
225
|
+
template ? /*#__PURE__*/ _jsx(TextField, {
|
|
226
|
+
label: "Body (from the template)",
|
|
227
|
+
value: template.body,
|
|
228
|
+
multiline: true,
|
|
229
|
+
minRows: 4,
|
|
230
|
+
fullWidth: true,
|
|
231
|
+
disabled: true
|
|
232
|
+
}) : /*#__PURE__*/ _jsx(TextField, {
|
|
233
|
+
label: "Body",
|
|
234
|
+
value: step.body,
|
|
235
|
+
inputRef: bodyRef,
|
|
236
|
+
onFocus: ()=>lastFocused.current = 'body',
|
|
237
|
+
onChange: (event)=>props.onChange(_extends({}, step, {
|
|
238
|
+
body: event.target.value
|
|
239
|
+
})),
|
|
240
|
+
disabled: disabled,
|
|
241
|
+
error: Boolean(issues['body']),
|
|
242
|
+
helperText: issues['body'],
|
|
243
|
+
multiline: true,
|
|
244
|
+
minRows: 6,
|
|
245
|
+
fullWidth: true
|
|
246
|
+
}),
|
|
247
|
+
/*#__PURE__*/ _jsx(Stack, {
|
|
248
|
+
direction: "row",
|
|
249
|
+
spacing: 1,
|
|
250
|
+
children: /*#__PURE__*/ _jsx(Button, {
|
|
251
|
+
size: "small",
|
|
252
|
+
variant: "outlined",
|
|
253
|
+
startIcon: /*#__PURE__*/ _jsx(MdiIcon, {
|
|
254
|
+
path: mdiCodeBraces.path,
|
|
255
|
+
fontSize: "small"
|
|
256
|
+
}),
|
|
257
|
+
onClick: (event)=>setFieldsAnchor(event.currentTarget),
|
|
258
|
+
disabled: disabled || Boolean(template) && !showSubject,
|
|
259
|
+
"aria-haspopup": "menu",
|
|
260
|
+
children: "Insert field"
|
|
261
|
+
})
|
|
262
|
+
}),
|
|
263
|
+
/*#__PURE__*/ _jsx(Menu, {
|
|
264
|
+
anchorEl: fieldsAnchor,
|
|
265
|
+
open: Boolean(fieldsAnchor),
|
|
266
|
+
onClose: ()=>setFieldsAnchor(null),
|
|
267
|
+
children: FIELD_GROUPS.flatMap((group)=>[
|
|
268
|
+
/*#__PURE__*/ _jsx(ListSubheader, {
|
|
269
|
+
children: group
|
|
270
|
+
}, `group-${group}`),
|
|
271
|
+
...OUTREACH_MERGE_FIELDS.filter((field)=>field.group === group).map((field)=>/*#__PURE__*/ _jsx(MenuItem, {
|
|
272
|
+
onClick: ()=>insertField(field.key),
|
|
273
|
+
children: field.label
|
|
274
|
+
}, field.key))
|
|
275
|
+
])
|
|
276
|
+
})
|
|
277
|
+
]
|
|
278
|
+
});
|
|
279
|
+
}
|
|
280
|
+
function TaskStepFields(props) {
|
|
281
|
+
var _issues_title;
|
|
282
|
+
const { step, disabled, issues } = props;
|
|
283
|
+
return /*#__PURE__*/ _jsxs(Stack, {
|
|
284
|
+
direction: {
|
|
285
|
+
xs: 'column',
|
|
286
|
+
sm: 'row'
|
|
287
|
+
},
|
|
288
|
+
spacing: 2,
|
|
289
|
+
children: [
|
|
290
|
+
/*#__PURE__*/ _jsx(TextField, {
|
|
291
|
+
select: true,
|
|
292
|
+
label: "Task",
|
|
293
|
+
value: OUTREACH_TASK_KINDS.includes(step.taskKind) ? step.taskKind : '',
|
|
294
|
+
onChange: (event)=>props.onChange(_extends({}, step, {
|
|
295
|
+
taskKind: event.target.value
|
|
296
|
+
})),
|
|
297
|
+
disabled: disabled,
|
|
298
|
+
error: Boolean(issues['taskKind']),
|
|
299
|
+
helperText: issues['taskKind'],
|
|
300
|
+
sx: {
|
|
301
|
+
minWidth: {
|
|
302
|
+
sm: 180
|
|
303
|
+
}
|
|
304
|
+
},
|
|
305
|
+
children: OUTREACH_TASK_KINDS.map((kind)=>/*#__PURE__*/ _jsx(MenuItem, {
|
|
306
|
+
value: kind,
|
|
307
|
+
children: OUTREACH_TASK_KIND_LABELS[kind]
|
|
308
|
+
}, kind))
|
|
309
|
+
}),
|
|
310
|
+
/*#__PURE__*/ _jsx(TextField, {
|
|
311
|
+
label: "Title",
|
|
312
|
+
value: step.title,
|
|
313
|
+
onChange: (event)=>props.onChange(_extends({}, step, {
|
|
314
|
+
title: event.target.value
|
|
315
|
+
})),
|
|
316
|
+
disabled: disabled,
|
|
317
|
+
error: Boolean(issues['title']),
|
|
318
|
+
helperText: (_issues_title = issues['title']) != null ? _issues_title : 'What the task says, for example “Connect on LinkedIn”.',
|
|
319
|
+
fullWidth: true
|
|
320
|
+
})
|
|
321
|
+
]
|
|
322
|
+
});
|
|
323
|
+
}
|
|
324
|
+
export default OutreachStepCard;
|
|
325
|
+
|
|
326
|
+
//# sourceMappingURL=sequence-step-card.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../../../libs/plugins/outreach/src/lib/components/sequence-step-card.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 mdiArrowDown,\n mdiArrowUp,\n mdiCodeBraces,\n mdiTrashCanOutline,\n} from '@aglyn/shared-data-mdi'\nimport { MdiIcon } from '@aglyn/shared-ui-jsx'\nimport {\n Autocomplete,\n Button,\n Card,\n CardContent,\n FormControlLabel,\n IconButton,\n ListSubheader,\n Menu,\n MenuItem,\n Stack,\n Switch,\n TextField,\n Tooltip,\n Typography,\n} from '@mui/material'\nimport { useRef, useState } from 'react'\nimport { OUTREACH_MERGE_FIELDS } from '../engine/sequence-validation'\nimport {\n OUTREACH_MAX_STEP_DELAY_BUSINESS_DAYS,\n OUTREACH_TASK_KIND_LABELS,\n OUTREACH_TASK_KINDS,\n type OutreachEmailStep,\n type OutreachSequenceStep,\n type OutreachTaskKind,\n type OutreachTaskStep,\n} from '../model/outreach.types'\nimport type { OutreachTemplateOption } from './use-outreach-crm'\n\nexport interface OutreachStepCardProps {\n step: OutreachSequenceStep\n /** Its position, from 0. */\n index: number\n /** How many steps the sequence has, for the move controls. */\n count: number\n /** Whether it is the sequence's first email, which always starts the thread. */\n firstEmail: boolean\n /** Whether it is sent as a reply in the thread an earlier email started. */\n inThread: boolean\n /** The subject the thread was started with, for an in-thread email's note. */\n threadSubject: string\n templates: readonly OutreachTemplateOption[]\n /** The issue to show beside each field, by the field's own name. */\n issues: Partial<Record<string, string>>\n disabled?: boolean\n onChange(step: OutreachSequenceStep): void\n onMove(direction: -1 | 1): void\n onRemove(): void\n}\n\n/** The merge fields, grouped the way the picker heads them. */\nconst FIELD_GROUPS = [\n ...new Set(OUTREACH_MERGE_FIELDS.map((field) => field.group)),\n]\n\n/**\n * One step of the sequence editor (AGL-2980): an email — subject, body or a\n * CRM template, merge fields, the wait before it — or a task for the rep.\n */\nexport function OutreachStepCard(props: OutreachStepCardProps) {\n const { step, index, count, disabled } = props\n const title =\n step.kind === 'email'\n ? `Step ${index + 1} · Email`\n : `Step ${index + 1} · ${OUTREACH_TASK_KIND_LABELS[(step as OutreachTaskStep).taskKind] ?? 'Task'}`\n return (\n <Card variant=\"outlined\" component=\"section\" aria-label={title}>\n <CardContent>\n <Stack spacing={2}>\n <Stack direction=\"row\" spacing={1} sx={{ alignItems: 'center' }}>\n <Typography variant=\"subtitle1\" sx={{ flexGrow: 1 }}>\n {title}\n </Typography>\n <Tooltip title=\"Move up\">\n <span>\n <IconButton\n size=\"small\"\n aria-label={`Move step ${index + 1} up`}\n disabled={disabled || index === 0}\n onClick={() => props.onMove(-1)}\n >\n <MdiIcon path={mdiArrowUp.path} fontSize=\"small\" />\n </IconButton>\n </span>\n </Tooltip>\n <Tooltip title=\"Move down\">\n <span>\n <IconButton\n size=\"small\"\n aria-label={`Move step ${index + 1} down`}\n disabled={disabled || index === count - 1}\n onClick={() => props.onMove(1)}\n >\n <MdiIcon path={mdiArrowDown.path} fontSize=\"small\" />\n </IconButton>\n </span>\n </Tooltip>\n <Tooltip title=\"Remove\">\n <span>\n <IconButton\n size=\"small\"\n aria-label={`Remove step ${index + 1}`}\n disabled={disabled || count === 1}\n onClick={props.onRemove}\n >\n <MdiIcon path={mdiTrashCanOutline.path} fontSize=\"small\" />\n </IconButton>\n </span>\n </Tooltip>\n </Stack>\n <DelayField {...props} />\n {step.kind === 'email' ? (\n <EmailStepFields {...props} step={step} />\n ) : step.kind === 'task' ? (\n <TaskStepFields {...props} step={step} />\n ) : (\n <Typography variant=\"body2\" color=\"error\">\n {props.issues['step'] ?? 'A step is an email or a task.'}\n </Typography>\n )}\n </Stack>\n </CardContent>\n </Card>\n )\n}\nOutreachStepCard.displayName = 'OutreachStepCard'\n\nfunction DelayField(props: OutreachStepCardProps) {\n const { step, index, disabled } = props\n const first = index === 0\n const issue = props.issues['delayBusinessDays']\n return (\n <TextField\n type=\"number\"\n label={\n first\n ? 'Wait after enrolling (business days)'\n : 'Wait after the step before (business days)'\n }\n value={\n Number.isFinite(step.delayBusinessDays) ? step.delayBusinessDays : ''\n }\n onChange={(event) =>\n props.onChange({\n ...step,\n delayBusinessDays:\n event.target.value === '' ? Number.NaN : Number(event.target.value),\n })\n }\n disabled={disabled}\n error={Boolean(issue)}\n helperText={\n issue ??\n (first\n ? '0 sends at the next opening of the sending hours.'\n : 'Counted in the mailbox’s timezone, skipping weekends.')\n }\n slotProps={{\n htmlInput: {\n min: 0,\n max: OUTREACH_MAX_STEP_DELAY_BUSINESS_DAYS,\n step: 1,\n },\n }}\n sx={{ maxWidth: { sm: 360 } }}\n />\n )\n}\n\nfunction EmailStepFields(\n props: OutreachStepCardProps & { step: OutreachEmailStep },\n) {\n const { step, disabled, issues } = props\n const subjectRef = useRef<HTMLInputElement | null>(null)\n const bodyRef = useRef<HTMLTextAreaElement | null>(null)\n const lastFocused = useRef<'subject' | 'body'>('body')\n const [fieldsAnchor, setFieldsAnchor] = useState<HTMLElement | null>(null)\n const template =\n props.templates.find((option) => option.id === step.templateId) ?? null\n const showSubject = !props.inThread\n\n /** Puts `{{key}}` where the caret was in the field last focused. */\n const insertField = (key: string) => {\n setFieldsAnchor(null)\n const token = `{{${key}}}`\n const target =\n lastFocused.current === 'subject' && showSubject\n ? 'subject'\n : template\n ? null\n : 'body'\n if (!target) return\n const element = target === 'subject' ? subjectRef.current : bodyRef.current\n const value = step[target]\n const start = element?.selectionStart ?? value.length\n const end = element?.selectionEnd ?? value.length\n props.onChange({\n ...step,\n [target]: `${value.slice(0, start)}${token}${value.slice(end)}`,\n })\n requestAnimationFrame(() => {\n element?.focus()\n element?.setSelectionRange(start + token.length, start + token.length)\n })\n }\n\n return (\n <Stack spacing={2}>\n {props.firstEmail ? null : (\n <FormControlLabel\n control={\n <Switch\n checked={step.replyInThread !== false}\n onChange={(event) =>\n props.onChange({ ...step, replyInThread: event.target.checked })\n }\n disabled={disabled}\n />\n }\n label=\"Reply in the same thread\"\n />\n )}\n {showSubject ? (\n <TextField\n label=\"Subject\"\n value={step.subject}\n inputRef={subjectRef}\n onFocus={() => (lastFocused.current = 'subject')}\n onChange={(event) =>\n props.onChange({ ...step, subject: event.target.value })\n }\n disabled={disabled}\n error={Boolean(issues['subject'])}\n helperText={issues['subject']}\n fullWidth\n />\n ) : (\n <Typography variant=\"body2\" color=\"text.secondary\">\n {props.threadSubject\n ? `Sent as a reply: “Re: ${props.threadSubject}”.`\n : 'Sent as a reply in the thread the earlier email started.'}\n </Typography>\n )}\n <Autocomplete<OutreachTemplateOption>\n options={[...props.templates]}\n value={template}\n getOptionLabel={(option) => option.name}\n isOptionEqualToValue={(option, value) => option.id === value.id}\n onChange={(_event, next) =>\n props.onChange({\n ...step,\n templateId: next?.id ?? null,\n body: next ? '' : step.body,\n })\n }\n disabled={disabled}\n renderInput={(params) => (\n <TextField\n {...params}\n label=\"CRM email template\"\n helperText={\n template\n ? 'The template’s body is sent; this step’s own subject is the one used.'\n : 'Optional. Pick one to send its body instead of writing it here.'\n }\n />\n )}\n />\n {template ? (\n <TextField\n label=\"Body (from the template)\"\n value={template.body}\n multiline\n minRows={4}\n fullWidth\n disabled\n />\n ) : (\n <TextField\n label=\"Body\"\n value={step.body}\n inputRef={bodyRef}\n onFocus={() => (lastFocused.current = 'body')}\n onChange={(event) =>\n props.onChange({ ...step, body: event.target.value })\n }\n disabled={disabled}\n error={Boolean(issues['body'])}\n helperText={issues['body']}\n multiline\n minRows={6}\n fullWidth\n />\n )}\n <Stack direction=\"row\" spacing={1}>\n <Button\n size=\"small\"\n variant=\"outlined\"\n startIcon={<MdiIcon path={mdiCodeBraces.path} fontSize=\"small\" />}\n onClick={(event) => setFieldsAnchor(event.currentTarget)}\n disabled={disabled || (Boolean(template) && !showSubject)}\n aria-haspopup=\"menu\"\n >\n Insert field\n </Button>\n </Stack>\n <Menu\n anchorEl={fieldsAnchor}\n open={Boolean(fieldsAnchor)}\n onClose={() => setFieldsAnchor(null)}\n >\n {FIELD_GROUPS.flatMap((group) => [\n <ListSubheader key={`group-${group}`}>{group}</ListSubheader>,\n ...OUTREACH_MERGE_FIELDS.filter((field) => field.group === group).map(\n (field) => (\n <MenuItem key={field.key} onClick={() => insertField(field.key)}>\n {field.label}\n </MenuItem>\n ),\n ),\n ])}\n </Menu>\n </Stack>\n )\n}\n\nfunction TaskStepFields(\n props: OutreachStepCardProps & { step: OutreachTaskStep },\n) {\n const { step, disabled, issues } = props\n return (\n <Stack direction={{ xs: 'column', sm: 'row' }} spacing={2}>\n <TextField\n select\n label=\"Task\"\n value={OUTREACH_TASK_KINDS.includes(step.taskKind) ? step.taskKind : ''}\n onChange={(event) =>\n props.onChange({\n ...step,\n taskKind: event.target.value as OutreachTaskKind,\n })\n }\n disabled={disabled}\n error={Boolean(issues['taskKind'])}\n helperText={issues['taskKind']}\n sx={{ minWidth: { sm: 180 } }}\n >\n {OUTREACH_TASK_KINDS.map((kind) => (\n <MenuItem key={kind} value={kind}>\n {OUTREACH_TASK_KIND_LABELS[kind]}\n </MenuItem>\n ))}\n </TextField>\n <TextField\n label=\"Title\"\n value={step.title}\n onChange={(event) =>\n props.onChange({ ...step, title: event.target.value })\n }\n disabled={disabled}\n error={Boolean(issues['title'])}\n helperText={\n issues['title'] ??\n 'What the task says, for example “Connect on LinkedIn”.'\n }\n fullWidth\n />\n </Stack>\n )\n}\n\nexport default OutreachStepCard\n"],"names":["mdiArrowDown","mdiArrowUp","mdiCodeBraces","mdiTrashCanOutline","MdiIcon","Autocomplete","Button","Card","CardContent","FormControlLabel","IconButton","ListSubheader","Menu","MenuItem","Stack","Switch","TextField","Tooltip","Typography","useRef","useState","OUTREACH_MERGE_FIELDS","OUTREACH_MAX_STEP_DELAY_BUSINESS_DAYS","OUTREACH_TASK_KIND_LABELS","OUTREACH_TASK_KINDS","FIELD_GROUPS","Set","map","field","group","OutreachStepCard","props","step","index","count","disabled","title","kind","taskKind","variant","component","aria-label","spacing","direction","sx","alignItems","flexGrow","span","size","onClick","onMove","path","fontSize","onRemove","DelayField","EmailStepFields","TaskStepFields","color","issues","displayName","first","issue","type","label","value","Number","isFinite","delayBusinessDays","onChange","event","target","NaN","error","Boolean","helperText","slotProps","htmlInput","min","max","maxWidth","sm","subjectRef","bodyRef","lastFocused","fieldsAnchor","setFieldsAnchor","template","templates","find","option","id","templateId","showSubject","inThread","insertField","key","token","current","element","start","selectionStart","length","end","selectionEnd","slice","requestAnimationFrame","focus","setSelectionRange","firstEmail","control","checked","replyInThread","subject","inputRef","onFocus","fullWidth","threadSubject","options","getOptionLabel","name","isOptionEqualToValue","_event","next","body","renderInput","params","multiline","minRows","startIcon","currentTarget","aria-haspopup","anchorEl","open","onClose","flatMap","filter","xs","select","includes","minWidth"],"mappings":"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"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { type ConsolePluginOrgMount } from '@aglyn/aglyn';
|
|
2
|
+
import type { OutreachMailbox } from '../model/outreach.types';
|
|
3
|
+
export interface OutreachSequencesSectionProps {
|
|
4
|
+
/** The organization the hub is mounted under; `null` until the shell knows it. */
|
|
5
|
+
orgId: string | null;
|
|
6
|
+
orgMount?: ConsolePluginOrgMount;
|
|
7
|
+
org?: Record<string, unknown> | null;
|
|
8
|
+
/** The section's own path: `/[orgSlug]/outreach/sequences`. */
|
|
9
|
+
sectionPath: string;
|
|
10
|
+
/** The path below the section: `[]`, `['new']`, `[id]` or `[id, 'enrollments']`. */
|
|
11
|
+
subpath: readonly string[];
|
|
12
|
+
/** The Mailboxes section: `/[orgSlug]/outreach/mailboxes`. */
|
|
13
|
+
mailboxesPath: string;
|
|
14
|
+
/** The Compliance section: `/[orgSlug]/outreach/compliance`. */
|
|
15
|
+
compliancePath: string;
|
|
16
|
+
}
|
|
17
|
+
/** The new-sequence page's segment below the section. */
|
|
18
|
+
export declare const OUTREACH_NEW_SEQUENCE_SEGMENT = "new";
|
|
19
|
+
/**
|
|
20
|
+
* The Sequences section (AGL-2980), and the pages below it: the list, a new
|
|
21
|
+
* sequence, and one sequence's steps and enrollments. Each is a real URL, so
|
|
22
|
+
* a sequence is a link a rep can keep and the back button walks them.
|
|
23
|
+
*/
|
|
24
|
+
export declare function OutreachSequencesSection(props: OutreachSequencesSectionProps): import("react").JSX.Element;
|
|
25
|
+
export declare namespace OutreachSequencesSection {
|
|
26
|
+
var displayName: string;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Every sequence: its mailbox, its status, and how many people it enrolled
|
|
30
|
+
* and where they stand — a table on wider screens, cards on a phone.
|
|
31
|
+
*/
|
|
32
|
+
export declare function OutreachSequenceList(props: {
|
|
33
|
+
orgId: string;
|
|
34
|
+
sectionPath: string;
|
|
35
|
+
mailboxes: readonly OutreachMailbox[];
|
|
36
|
+
}): import("react").JSX.Element;
|
|
37
|
+
export declare namespace OutreachSequenceList {
|
|
38
|
+
var displayName: string;
|
|
39
|
+
}
|
|
40
|
+
export default OutreachSequencesSection;
|