@aglyn/plugins-outreach 1.0.0-beta.230 → 1.0.0-beta.232
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/package.json +14 -14
- package/src/lib/components/curated-step-editor.js +1 -0
- package/src/lib/components/curated-step-editor.js.map +1 -1
- package/src/lib/components/enroll-dialog.js +6 -0
- package/src/lib/components/enroll-dialog.js.map +1 -1
- package/src/lib/components/enrollment-detail.js +3 -0
- package/src/lib/components/enrollment-detail.js.map +1 -1
- package/src/lib/components/enrollments-table.js +1 -0
- package/src/lib/components/enrollments-table.js.map +1 -1
- package/src/lib/components/link-domains-card.js +2 -0
- package/src/lib/components/link-domains-card.js.map +1 -1
- package/src/lib/components/mailboxes-section.js +1 -0
- package/src/lib/components/mailboxes-section.js.map +1 -1
- package/src/lib/components/sequence-detail.js +1 -0
- package/src/lib/components/sequence-detail.js.map +1 -1
- package/src/lib/components/sequence-report-card.js +1 -0
- package/src/lib/components/sequence-report-card.js.map +1 -1
- package/src/lib/components/sequences-section.js +1 -0
- package/src/lib/components/sequences-section.js.map +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aglyn/plugins-outreach",
|
|
3
|
-
"version": "1.0.0-beta.
|
|
3
|
+
"version": "1.0.0-beta.232",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"homepage": "https://aglyn.com",
|
|
6
6
|
"repository": {
|
|
@@ -25,19 +25,19 @@
|
|
|
25
25
|
"./package.json": "./package.json"
|
|
26
26
|
},
|
|
27
27
|
"dependencies": {
|
|
28
|
-
"@aglyn/aglyn": "1.0.0-beta.
|
|
29
|
-
"@aglyn/shared-data-mdi": "1.0.0-beta.
|
|
30
|
-
"@aglyn/shared-ui-email-campaigns": "1.0.0-beta.
|
|
31
|
-
"@aglyn/shared-ui-jsx": "1.0.0-beta.
|
|
32
|
-
"@aglyn/shared-ui-next": "1.0.0-beta.
|
|
33
|
-
"@aglyn/shared-ui-snackstack": "1.0.0-beta.
|
|
34
|
-
"@aglyn/shared-util-email": "1.0.0-beta.
|
|
35
|
-
"@aglyn/shared-util-http": "1.0.0-beta.
|
|
36
|
-
"@aglyn/shared-util-timestamp": "1.0.0-beta.
|
|
37
|
-
"@aglyn/shared-util-tools": "1.0.0-beta.
|
|
38
|
-
"@aglyn/tenant-data-admin": "1.0.0-beta.
|
|
39
|
-
"@aglyn/tenant-feature-instance": "1.0.0-beta.
|
|
40
|
-
"@aglyn/tenant-runtime": "1.0.0-beta.
|
|
28
|
+
"@aglyn/aglyn": "1.0.0-beta.232",
|
|
29
|
+
"@aglyn/shared-data-mdi": "1.0.0-beta.232",
|
|
30
|
+
"@aglyn/shared-ui-email-campaigns": "1.0.0-beta.232",
|
|
31
|
+
"@aglyn/shared-ui-jsx": "1.0.0-beta.232",
|
|
32
|
+
"@aglyn/shared-ui-next": "1.0.0-beta.232",
|
|
33
|
+
"@aglyn/shared-ui-snackstack": "1.0.0-beta.232",
|
|
34
|
+
"@aglyn/shared-util-email": "1.0.0-beta.232",
|
|
35
|
+
"@aglyn/shared-util-http": "1.0.0-beta.232",
|
|
36
|
+
"@aglyn/shared-util-timestamp": "1.0.0-beta.232",
|
|
37
|
+
"@aglyn/shared-util-tools": "1.0.0-beta.232",
|
|
38
|
+
"@aglyn/tenant-data-admin": "1.0.0-beta.232",
|
|
39
|
+
"@aglyn/tenant-feature-instance": "1.0.0-beta.232",
|
|
40
|
+
"@aglyn/tenant-runtime": "1.0.0-beta.232",
|
|
41
41
|
"@swc/helpers": "0.5.23"
|
|
42
42
|
},
|
|
43
43
|
"peerDependencies": {
|
|
@@ -101,6 +101,7 @@ export function OutreachCuratedStepEditor(props) {
|
|
|
101
101
|
},
|
|
102
102
|
"aria-label": `${label} — ${draft.decision === 'use' ? 'curated' : 'template kept'}`,
|
|
103
103
|
children: /*#__PURE__*/ _jsxs(Stack, {
|
|
104
|
+
useFlexGap: true,
|
|
104
105
|
direction: "row",
|
|
105
106
|
spacing: 1,
|
|
106
107
|
sx: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../../../libs/plugins/outreach/src/lib/components/curated-step-editor.tsx"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n'use client'\n\nimport {\n Alert,\n Button,\n Checkbox,\n Chip,\n FormControlLabel,\n Paper,\n Stack,\n TextField,\n Typography,\n} from '@mui/material'\nimport { useMemo } from 'react'\nimport {\n isInThreadEmailStep,\n validateOutreachCuratedStep,\n type OutreachValidationIssue,\n} from '../engine/sequence-validation'\nimport type { OutreachCurateDraft, OutreachStepOverrideRequest } from '../model/outreach-api'\nimport {\n OUTREACH_CURATION_CONFIRMATION_LABEL,\n type OutreachSequenceStep,\n type OutreachStepOverrideSource,\n} from '../model/outreach.types'\n\n/**\n * ONE PERSON'S COPY OF ONE STEP, AS THE MEMBER READS AND DECIDES IT\n * (AGL-3324).\n *\n * The enroll dialog shows one of these under each person for every email\n * step the AI drafted; the Enrollments tab shows one for the next step. The\n * member edits the subject and the body, reads what the validator says,\n * ticks the confirmation — a fourth attestation beside the three a cold\n * contact asks for — and either USES the copy or KEEPS the template. Until\n * they decide, nothing about the draft leaves the browser: the enroll and\n * the save carry only what was used.\n *\n * Validated as they type, with the same rules the route applies again: a\n * draft that breaks one cannot be used as it stands.\n */\n\n/** What the member holds for one drafted step. */\nexport interface OutreachCuratedDraftState {\n stepIndex: number\n /** Whether the email starts a thread, and so has a subject of its own. */\n startsThread: boolean\n subject: string\n body: string\n /** The words as they were drafted, so an edit can be told from a confirmation. */\n original: { subject: string; body: string }\n source: OutreachStepOverrideSource\n /** The member ticked the confirmation. */\n confirmed: boolean\n /** Used, kept as the template, or still open. */\n decision: 'pending' | 'use' | 'keep'\n /** The AI's prompt and model, for the override's audit record. */\n prompt?: string\n model?: string\n}\n\n/** A drafted step as the route answered it, ready for the member. */\nexport function outreachDraftState(\n draft: Pick<OutreachCurateDraft, 'stepIndex' | 'subject' | 'body'>,\n steps: readonly OutreachSequenceStep[],\n source: OutreachStepOverrideSource,\n audit?: { prompt: string; model: string },\n): OutreachCuratedDraftState {\n const startsThread = !isInThreadEmailStep(steps, draft.stepIndex)\n const subject = startsThread ? (draft.subject ?? '') : ''\n return {\n stepIndex: draft.stepIndex,\n startsThread,\n subject,\n body: draft.body,\n original: { subject, body: draft.body },\n source,\n confirmed: false,\n decision: 'pending',\n ...(audit ? { prompt: audit.prompt, model: audit.model } : {}),\n }\n}\n\n/** The member's own starting point: the step's words, for them to rewrite by hand. */\nexport function outreachMemberDraftStates(\n steps: readonly OutreachSequenceStep[],\n stepIndexes: readonly number[],\n): OutreachCuratedDraftState[] {\n return stepIndexes.flatMap((stepIndex) => {\n const step = steps[stepIndex]\n if (step?.kind !== 'email') return []\n return [\n outreachDraftState(\n // A step that sends a CRM template has no words here to start from.\n { stepIndex, subject: step.subject, body: step.templateId ? '' : step.body },\n steps,\n 'member',\n ),\n ]\n })\n}\n\n/** The request a USED draft becomes; `null` for one that was kept or is still open. */\nexport function outreachDraftToOverride(\n draft: OutreachCuratedDraftState,\n): OutreachStepOverrideRequest | null {\n if (draft.decision !== 'use') return null\n const edited =\n draft.source === 'ai' &&\n (draft.body !== draft.original.body || (draft.startsThread && draft.subject !== draft.original.subject))\n return {\n stepIndex: draft.stepIndex,\n ...(draft.startsThread ? { subject: draft.subject } : {}),\n body: draft.body,\n source: draft.source,\n ...(edited ? { edited: true } : {}),\n ...(draft.source === 'ai' && draft.prompt ? { prompt: draft.prompt } : {}),\n ...(draft.source === 'ai' && draft.model ? { model: draft.model } : {}),\n }\n}\n\n/** The validator's verdict on the draft as it stands. */\nexport function outreachDraftIssues(draft: OutreachCuratedDraftState): OutreachValidationIssue[] {\n return validateOutreachCuratedStep(\n { subject: draft.startsThread ? draft.subject : undefined, body: draft.body, startsThread: draft.startsThread },\n `stepOverrides.${draft.stepIndex}`,\n )\n}\n\n/** Whether the draft may be used as it stands: confirmed, and nothing the validator refuses. */\nexport function outreachDraftUsable(draft: OutreachCuratedDraftState): boolean {\n return draft.confirmed && !outreachDraftIssues(draft).some((issue) => issue.severity === 'error')\n}\n\nexport interface OutreachCuratedStepEditorProps {\n draft: OutreachCuratedDraftState\n /** \"Email 1 · step 1\", as the sequence's preview names it. */\n label: string\n onChange(next: OutreachCuratedDraftState): void\n disabled?: boolean\n}\n\nexport function OutreachCuratedStepEditor(props: OutreachCuratedStepEditorProps) {\n const { draft, label, onChange } = props\n const disabled = props.disabled === true\n const issues = useMemo(() => outreachDraftIssues(draft), [draft])\n const errors = issues.filter((issue) => issue.severity === 'error')\n const warnings = issues.filter((issue) => issue.severity === 'warning')\n const change = (next: Partial<OutreachCuratedDraftState>) => onChange({ ...draft, ...next })\n const who = draft.source === 'ai' ? 'AI draft' : 'Your words'\n\n if (draft.decision !== 'pending') {\n return (\n <Paper variant=\"outlined\" sx={{ p: 1.5 }} aria-label={`${label} — ${draft.decision === 'use' ? 'curated' : 'template kept'}`}>\n <Stack direction=\"row\" spacing={1} sx={{ alignItems: 'center', flexWrap: 'wrap', rowGap: 1 }}>\n <Typography variant=\"body2\" sx={{ flexGrow: 1 }}>\n {label}\n </Typography>\n <Chip\n size=\"small\"\n color={draft.decision === 'use' ? 'success' : 'default'}\n label={draft.decision === 'use' ? `Curated · ${who}` : 'Template kept'}\n />\n <Button size=\"small\" onClick={() => change({ decision: 'pending' })} disabled={disabled}>\n Change\n </Button>\n </Stack>\n </Paper>\n )\n }\n\n return (\n <Paper variant=\"outlined\" sx={{ p: 1.5 }} aria-label={`${label} — draft`}>\n <Stack spacing={1.5}>\n <Stack direction=\"row\" spacing={1} sx={{ alignItems: 'center' }}>\n <Typography variant=\"subtitle2\" sx={{ flexGrow: 1 }}>\n {label}\n </Typography>\n <Chip size=\"small\" variant=\"outlined\" label={who} />\n </Stack>\n {draft.startsThread ? (\n <TextField\n label=\"Subject\"\n value={draft.subject}\n onChange={(event) => change({ subject: event.target.value, confirmed: false })}\n disabled={disabled}\n size=\"small\"\n fullWidth\n error={errors.some((issue) => issue.path.endsWith('.subject'))}\n />\n ) : (\n <Typography variant=\"caption\" color=\"text.secondary\">\n Sent as a reply in the thread, under the thread’s subject.\n </Typography>\n )}\n <TextField\n label=\"Email\"\n value={draft.body}\n onChange={(event) => change({ body: event.target.value, confirmed: false })}\n disabled={disabled}\n multiline\n minRows={6}\n fullWidth\n error={errors.some((issue) => issue.path.endsWith('.body'))}\n helperText=\"Plain text. The footer is added when it’s sent.\"\n />\n {errors.length ? (\n <Alert severity=\"error\">\n <Stack component=\"ul\" spacing={0.5} sx={{ m: 0, pl: 2 }}>\n {errors.map((issue) => (\n <li key={`${issue.path}:${issue.code}`}>{issue.message}</li>\n ))}\n </Stack>\n </Alert>\n ) : null}\n {warnings.length ? (\n <Typography variant=\"caption\" color=\"text.secondary\">\n {warnings.map((issue) => issue.message).join(' ')}\n </Typography>\n ) : null}\n <FormControlLabel\n control={\n <Checkbox\n checked={draft.confirmed}\n onChange={(event) => change({ confirmed: event.target.checked })}\n disabled={disabled || errors.length > 0}\n />\n }\n label={OUTREACH_CURATION_CONFIRMATION_LABEL}\n />\n <Stack direction=\"row\" spacing={1}>\n <Button\n size=\"small\"\n variant=\"contained\"\n disabled={disabled || !outreachDraftUsable(draft)}\n onClick={() => change({ decision: 'use' })}\n >\n Use this\n </Button>\n <Button size=\"small\" disabled={disabled} onClick={() => change({ decision: 'keep' })}>\n Keep the template\n </Button>\n </Stack>\n </Stack>\n </Paper>\n )\n}\nOutreachCuratedStepEditor.displayName = 'OutreachCuratedStepEditor'\n\nexport default OutreachCuratedStepEditor\n"],"names":["Alert","Button","Checkbox","Chip","FormControlLabel","Paper","Stack","TextField","Typography","useMemo","isInThreadEmailStep","validateOutreachCuratedStep","OUTREACH_CURATION_CONFIRMATION_LABEL","outreachDraftState","draft","steps","source","audit","startsThread","stepIndex","subject","body","original","confirmed","decision","prompt","model","outreachMemberDraftStates","stepIndexes","flatMap","step","kind","templateId","outreachDraftToOverride","edited","outreachDraftIssues","undefined","outreachDraftUsable","some","issue","severity","OutreachCuratedStepEditor","props","label","onChange","disabled","issues","errors","filter","warnings","change","next","who","variant","sx","p","aria-label","direction","spacing","alignItems","flexWrap","rowGap","flexGrow","size","color","onClick","value","event","target","fullWidth","error","path","endsWith","multiline","minRows","helperText","length","component","m","pl","map","li","message","code","join","control","checked","displayName"],"mappings":"AAAA;;;;;;;;;;;;;;;CAeC,GAED;;;AAEA,SACEA,KAAK,EACLC,MAAM,EACNC,QAAQ,EACRC,IAAI,EACJC,gBAAgB,EAChBC,KAAK,EACLC,KAAK,EACLC,SAAS,EACTC,UAAU,QACL,gBAAe;AACtB,SAASC,OAAO,QAAQ,QAAO;AAC/B,SACEC,mBAAmB,EACnBC,2BAA2B,QAEtB,mCAA+B;AAEtC,SACEC,oCAAoC,QAG/B,6BAAyB;AAqChC,mEAAmE,GACnE,OAAO,SAASC,mBACdC,KAAkE,EAClEC,KAAsC,EACtCC,MAAkC,EAClCC,KAAyC;QAGTH;IADhC,MAAMI,eAAe,CAACR,oBAAoBK,OAAOD,MAAMK,SAAS;IAChE,MAAMC,UAAUF,gBAAgBJ,iBAAAA,MAAMM,OAAO,YAAbN,iBAAiB,KAAM;IACvD,OAAO;QACLK,WAAWL,MAAMK,SAAS;QAC1BD;QACAE;QACAC,MAAMP,MAAMO,IAAI;QAChBC,UAAU;YAAEF;YAASC,MAAMP,MAAMO,IAAI;QAAC;QACtCL;QACAO,WAAW;QACXC,UAAU;OACNP,QAAQ;QAAEQ,QAAQR,MAAMQ,MAAM;QAAEC,OAAOT,MAAMS,KAAK;IAAC,IAAI,CAAC;AAEhE;AAEA,oFAAoF,GACpF,OAAO,SAASC,0BACdZ,KAAsC,EACtCa,WAA8B;IAE9B,OAAOA,YAAYC,OAAO,CAAC,CAACV;QAC1B,MAAMW,OAAOf,KAAK,CAACI,UAAU;QAC7B,IAAIW,CAAAA,wBAAAA,KAAMC,IAAI,MAAK,SAAS,OAAO,EAAE;QACrC,OAAO;YACLlB,mBACE,oEAAoE;YACpE;gBAAEM;gBAAWC,SAASU,KAAKV,OAAO;gBAAEC,MAAMS,KAAKE,UAAU,GAAG,KAAKF,KAAKT,IAAI;YAAC,GAC3EN,OACA;SAEH;IACH;AACF;AAEA,qFAAqF,GACrF,OAAO,SAASkB,wBACdnB,KAAgC;IAEhC,IAAIA,MAAMU,QAAQ,KAAK,OAAO,OAAO;IACrC,MAAMU,SACJpB,MAAME,MAAM,KAAK,QAChBF,CAAAA,MAAMO,IAAI,KAAKP,MAAMQ,QAAQ,CAACD,IAAI,IAAKP,MAAMI,YAAY,IAAIJ,MAAMM,OAAO,KAAKN,MAAMQ,QAAQ,CAACF,OAAO;IACxG,OAAO;QACLD,WAAWL,MAAMK,SAAS;OACtBL,MAAMI,YAAY,GAAG;QAAEE,SAASN,MAAMM,OAAO;IAAC,IAAI,CAAC;QACvDC,MAAMP,MAAMO,IAAI;QAChBL,QAAQF,MAAME,MAAM;OAChBkB,SAAS;QAAEA,QAAQ;IAAK,IAAI,CAAC,GAC7BpB,MAAME,MAAM,KAAK,QAAQF,MAAMW,MAAM,GAAG;QAAEA,QAAQX,MAAMW,MAAM;IAAC,IAAI,CAAC,GACpEX,MAAME,MAAM,KAAK,QAAQF,MAAMY,KAAK,GAAG;QAAEA,OAAOZ,MAAMY,KAAK;IAAC,IAAI,CAAC;AAEzE;AAEA,uDAAuD,GACvD,OAAO,SAASS,oBAAoBrB,KAAgC;IAClE,OAAOH,4BACL;QAAES,SAASN,MAAMI,YAAY,GAAGJ,MAAMM,OAAO,GAAGgB;QAAWf,MAAMP,MAAMO,IAAI;QAAEH,cAAcJ,MAAMI,YAAY;IAAC,GAC9G,CAAC,cAAc,EAAEJ,MAAMK,SAAS,EAAE;AAEtC;AAEA,8FAA8F,GAC9F,OAAO,SAASkB,oBAAoBvB,KAAgC;IAClE,OAAOA,MAAMS,SAAS,IAAI,CAACY,oBAAoBrB,OAAOwB,IAAI,CAAC,CAACC,QAAUA,MAAMC,QAAQ,KAAK;AAC3F;AAUA,OAAO,SAASC,0BAA0BC,KAAqC;IAC7E,MAAM,EAAE5B,KAAK,EAAE6B,KAAK,EAAEC,QAAQ,EAAE,GAAGF;IACnC,MAAMG,WAAWH,MAAMG,QAAQ,KAAK;IACpC,MAAMC,SAASrC,QAAQ,IAAM0B,oBAAoBrB,QAAQ;QAACA;KAAM;IAChE,MAAMiC,SAASD,OAAOE,MAAM,CAAC,CAACT,QAAUA,MAAMC,QAAQ,KAAK;IAC3D,MAAMS,WAAWH,OAAOE,MAAM,CAAC,CAACT,QAAUA,MAAMC,QAAQ,KAAK;IAC7D,MAAMU,SAAS,CAACC,OAA6CP,SAAS,aAAK9B,OAAUqC;IACrF,MAAMC,MAAMtC,MAAME,MAAM,KAAK,OAAO,aAAa;IAEjD,IAAIF,MAAMU,QAAQ,KAAK,WAAW;QAChC,qBACE,KAACnB;YAAMgD,SAAQ;YAAWC,IAAI;gBAAEC,GAAG;YAAI;YAAGC,cAAY,GAAGb,MAAM,GAAG,EAAE7B,MAAMU,QAAQ,KAAK,QAAQ,YAAY,iBAAiB;sBAC1H,cAAA,MAAClB;gBAAMmD,WAAU;gBAAMC,SAAS;gBAAGJ,IAAI;oBAAEK,YAAY;oBAAUC,UAAU;oBAAQC,QAAQ;gBAAE;;kCACzF,KAACrD;wBAAW6C,SAAQ;wBAAQC,IAAI;4BAAEQ,UAAU;wBAAE;kCAC3CnB;;kCAEH,KAACxC;wBACC4D,MAAK;wBACLC,OAAOlD,MAAMU,QAAQ,KAAK,QAAQ,YAAY;wBAC9CmB,OAAO7B,MAAMU,QAAQ,KAAK,QAAQ,CAAC,UAAU,EAAE4B,KAAK,GAAG;;kCAEzD,KAACnD;wBAAO8D,MAAK;wBAAQE,SAAS,IAAMf,OAAO;gCAAE1B,UAAU;4BAAU;wBAAIqB,UAAUA;kCAAU;;;;;IAMjG;IAEA,qBACE,KAACxC;QAAMgD,SAAQ;QAAWC,IAAI;YAAEC,GAAG;QAAI;QAAGC,cAAY,GAAGb,MAAM,QAAQ,CAAC;kBACtE,cAAA,MAACrC;YAAMoD,SAAS;;8BACd,MAACpD;oBAAMmD,WAAU;oBAAMC,SAAS;oBAAGJ,IAAI;wBAAEK,YAAY;oBAAS;;sCAC5D,KAACnD;4BAAW6C,SAAQ;4BAAYC,IAAI;gCAAEQ,UAAU;4BAAE;sCAC/CnB;;sCAEH,KAACxC;4BAAK4D,MAAK;4BAAQV,SAAQ;4BAAWV,OAAOS;;;;gBAE9CtC,MAAMI,YAAY,iBACjB,KAACX;oBACCoC,OAAM;oBACNuB,OAAOpD,MAAMM,OAAO;oBACpBwB,UAAU,CAACuB,QAAUjB,OAAO;4BAAE9B,SAAS+C,MAAMC,MAAM,CAACF,KAAK;4BAAE3C,WAAW;wBAAM;oBAC5EsB,UAAUA;oBACVkB,MAAK;oBACLM,SAAS;oBACTC,OAAOvB,OAAOT,IAAI,CAAC,CAACC,QAAUA,MAAMgC,IAAI,CAACC,QAAQ,CAAC;mCAGpD,KAAChE;oBAAW6C,SAAQ;oBAAUW,OAAM;8BAAiB;;8BAIvD,KAACzD;oBACCoC,OAAM;oBACNuB,OAAOpD,MAAMO,IAAI;oBACjBuB,UAAU,CAACuB,QAAUjB,OAAO;4BAAE7B,MAAM8C,MAAMC,MAAM,CAACF,KAAK;4BAAE3C,WAAW;wBAAM;oBACzEsB,UAAUA;oBACV4B,SAAS;oBACTC,SAAS;oBACTL,SAAS;oBACTC,OAAOvB,OAAOT,IAAI,CAAC,CAACC,QAAUA,MAAMgC,IAAI,CAACC,QAAQ,CAAC;oBAClDG,YAAW;;gBAEZ5B,OAAO6B,MAAM,iBACZ,KAAC5E;oBAAMwC,UAAS;8BACd,cAAA,KAAClC;wBAAMuE,WAAU;wBAAKnB,SAAS;wBAAKJ,IAAI;4BAAEwB,GAAG;4BAAGC,IAAI;wBAAE;kCACnDhC,OAAOiC,GAAG,CAAC,CAACzC,sBACX,KAAC0C;0CAAwC1C,MAAM2C,OAAO;+BAA7C,GAAG3C,MAAMgC,IAAI,CAAC,CAAC,EAAEhC,MAAM4C,IAAI,EAAE;;qBAI1C;gBACHlC,SAAS2B,MAAM,iBACd,KAACpE;oBAAW6C,SAAQ;oBAAUW,OAAM;8BACjCf,SAAS+B,GAAG,CAAC,CAACzC,QAAUA,MAAM2C,OAAO,EAAEE,IAAI,CAAC;qBAE7C;8BACJ,KAAChF;oBACCiF,uBACE,KAACnF;wBACCoF,SAASxE,MAAMS,SAAS;wBACxBqB,UAAU,CAACuB,QAAUjB,OAAO;gCAAE3B,WAAW4C,MAAMC,MAAM,CAACkB,OAAO;4BAAC;wBAC9DzC,UAAUA,YAAYE,OAAO6B,MAAM,GAAG;;oBAG1CjC,OAAO/B;;8BAET,MAACN;oBAAMmD,WAAU;oBAAMC,SAAS;;sCAC9B,KAACzD;4BACC8D,MAAK;4BACLV,SAAQ;4BACRR,UAAUA,YAAY,CAACR,oBAAoBvB;4BAC3CmD,SAAS,IAAMf,OAAO;oCAAE1B,UAAU;gCAAM;sCACzC;;sCAGD,KAACvB;4BAAO8D,MAAK;4BAAQlB,UAAUA;4BAAUoB,SAAS,IAAMf,OAAO;oCAAE1B,UAAU;gCAAO;sCAAI;;;;;;;AAOhG;AACAiB,0BAA0B8C,WAAW,GAAG;AAExC,eAAe9C,0BAAyB"}
|
|
1
|
+
{"version":3,"sources":["../../../../../../../libs/plugins/outreach/src/lib/components/curated-step-editor.tsx"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n'use client'\n\nimport {\n Alert,\n Button,\n Checkbox,\n Chip,\n FormControlLabel,\n Paper,\n Stack,\n TextField,\n Typography,\n} from '@mui/material'\nimport { useMemo } from 'react'\nimport {\n isInThreadEmailStep,\n validateOutreachCuratedStep,\n type OutreachValidationIssue,\n} from '../engine/sequence-validation'\nimport type { OutreachCurateDraft, OutreachStepOverrideRequest } from '../model/outreach-api'\nimport {\n OUTREACH_CURATION_CONFIRMATION_LABEL,\n type OutreachSequenceStep,\n type OutreachStepOverrideSource,\n} from '../model/outreach.types'\n\n/**\n * ONE PERSON'S COPY OF ONE STEP, AS THE MEMBER READS AND DECIDES IT\n * (AGL-3324).\n *\n * The enroll dialog shows one of these under each person for every email\n * step the AI drafted; the Enrollments tab shows one for the next step. The\n * member edits the subject and the body, reads what the validator says,\n * ticks the confirmation — a fourth attestation beside the three a cold\n * contact asks for — and either USES the copy or KEEPS the template. Until\n * they decide, nothing about the draft leaves the browser: the enroll and\n * the save carry only what was used.\n *\n * Validated as they type, with the same rules the route applies again: a\n * draft that breaks one cannot be used as it stands.\n */\n\n/** What the member holds for one drafted step. */\nexport interface OutreachCuratedDraftState {\n stepIndex: number\n /** Whether the email starts a thread, and so has a subject of its own. */\n startsThread: boolean\n subject: string\n body: string\n /** The words as they were drafted, so an edit can be told from a confirmation. */\n original: { subject: string; body: string }\n source: OutreachStepOverrideSource\n /** The member ticked the confirmation. */\n confirmed: boolean\n /** Used, kept as the template, or still open. */\n decision: 'pending' | 'use' | 'keep'\n /** The AI's prompt and model, for the override's audit record. */\n prompt?: string\n model?: string\n}\n\n/** A drafted step as the route answered it, ready for the member. */\nexport function outreachDraftState(\n draft: Pick<OutreachCurateDraft, 'stepIndex' | 'subject' | 'body'>,\n steps: readonly OutreachSequenceStep[],\n source: OutreachStepOverrideSource,\n audit?: { prompt: string; model: string },\n): OutreachCuratedDraftState {\n const startsThread = !isInThreadEmailStep(steps, draft.stepIndex)\n const subject = startsThread ? (draft.subject ?? '') : ''\n return {\n stepIndex: draft.stepIndex,\n startsThread,\n subject,\n body: draft.body,\n original: { subject, body: draft.body },\n source,\n confirmed: false,\n decision: 'pending',\n ...(audit ? { prompt: audit.prompt, model: audit.model } : {}),\n }\n}\n\n/** The member's own starting point: the step's words, for them to rewrite by hand. */\nexport function outreachMemberDraftStates(\n steps: readonly OutreachSequenceStep[],\n stepIndexes: readonly number[],\n): OutreachCuratedDraftState[] {\n return stepIndexes.flatMap((stepIndex) => {\n const step = steps[stepIndex]\n if (step?.kind !== 'email') return []\n return [\n outreachDraftState(\n // A step that sends a CRM template has no words here to start from.\n { stepIndex, subject: step.subject, body: step.templateId ? '' : step.body },\n steps,\n 'member',\n ),\n ]\n })\n}\n\n/** The request a USED draft becomes; `null` for one that was kept or is still open. */\nexport function outreachDraftToOverride(\n draft: OutreachCuratedDraftState,\n): OutreachStepOverrideRequest | null {\n if (draft.decision !== 'use') return null\n const edited =\n draft.source === 'ai' &&\n (draft.body !== draft.original.body || (draft.startsThread && draft.subject !== draft.original.subject))\n return {\n stepIndex: draft.stepIndex,\n ...(draft.startsThread ? { subject: draft.subject } : {}),\n body: draft.body,\n source: draft.source,\n ...(edited ? { edited: true } : {}),\n ...(draft.source === 'ai' && draft.prompt ? { prompt: draft.prompt } : {}),\n ...(draft.source === 'ai' && draft.model ? { model: draft.model } : {}),\n }\n}\n\n/** The validator's verdict on the draft as it stands. */\nexport function outreachDraftIssues(draft: OutreachCuratedDraftState): OutreachValidationIssue[] {\n return validateOutreachCuratedStep(\n { subject: draft.startsThread ? draft.subject : undefined, body: draft.body, startsThread: draft.startsThread },\n `stepOverrides.${draft.stepIndex}`,\n )\n}\n\n/** Whether the draft may be used as it stands: confirmed, and nothing the validator refuses. */\nexport function outreachDraftUsable(draft: OutreachCuratedDraftState): boolean {\n return draft.confirmed && !outreachDraftIssues(draft).some((issue) => issue.severity === 'error')\n}\n\nexport interface OutreachCuratedStepEditorProps {\n draft: OutreachCuratedDraftState\n /** \"Email 1 · step 1\", as the sequence's preview names it. */\n label: string\n onChange(next: OutreachCuratedDraftState): void\n disabled?: boolean\n}\n\nexport function OutreachCuratedStepEditor(props: OutreachCuratedStepEditorProps) {\n const { draft, label, onChange } = props\n const disabled = props.disabled === true\n const issues = useMemo(() => outreachDraftIssues(draft), [draft])\n const errors = issues.filter((issue) => issue.severity === 'error')\n const warnings = issues.filter((issue) => issue.severity === 'warning')\n const change = (next: Partial<OutreachCuratedDraftState>) => onChange({ ...draft, ...next })\n const who = draft.source === 'ai' ? 'AI draft' : 'Your words'\n\n if (draft.decision !== 'pending') {\n return (\n <Paper variant=\"outlined\" sx={{ p: 1.5 }} aria-label={`${label} — ${draft.decision === 'use' ? 'curated' : 'template kept'}`}>\n <Stack useFlexGap direction=\"row\" spacing={1} sx={{ alignItems: 'center', flexWrap: 'wrap', rowGap: 1 }}>\n <Typography variant=\"body2\" sx={{ flexGrow: 1 }}>\n {label}\n </Typography>\n <Chip\n size=\"small\"\n color={draft.decision === 'use' ? 'success' : 'default'}\n label={draft.decision === 'use' ? `Curated · ${who}` : 'Template kept'}\n />\n <Button size=\"small\" onClick={() => change({ decision: 'pending' })} disabled={disabled}>\n Change\n </Button>\n </Stack>\n </Paper>\n )\n }\n\n return (\n <Paper variant=\"outlined\" sx={{ p: 1.5 }} aria-label={`${label} — draft`}>\n <Stack spacing={1.5}>\n <Stack direction=\"row\" spacing={1} sx={{ alignItems: 'center' }}>\n <Typography variant=\"subtitle2\" sx={{ flexGrow: 1 }}>\n {label}\n </Typography>\n <Chip size=\"small\" variant=\"outlined\" label={who} />\n </Stack>\n {draft.startsThread ? (\n <TextField\n label=\"Subject\"\n value={draft.subject}\n onChange={(event) => change({ subject: event.target.value, confirmed: false })}\n disabled={disabled}\n size=\"small\"\n fullWidth\n error={errors.some((issue) => issue.path.endsWith('.subject'))}\n />\n ) : (\n <Typography variant=\"caption\" color=\"text.secondary\">\n Sent as a reply in the thread, under the thread’s subject.\n </Typography>\n )}\n <TextField\n label=\"Email\"\n value={draft.body}\n onChange={(event) => change({ body: event.target.value, confirmed: false })}\n disabled={disabled}\n multiline\n minRows={6}\n fullWidth\n error={errors.some((issue) => issue.path.endsWith('.body'))}\n helperText=\"Plain text. The footer is added when it’s sent.\"\n />\n {errors.length ? (\n <Alert severity=\"error\">\n <Stack component=\"ul\" spacing={0.5} sx={{ m: 0, pl: 2 }}>\n {errors.map((issue) => (\n <li key={`${issue.path}:${issue.code}`}>{issue.message}</li>\n ))}\n </Stack>\n </Alert>\n ) : null}\n {warnings.length ? (\n <Typography variant=\"caption\" color=\"text.secondary\">\n {warnings.map((issue) => issue.message).join(' ')}\n </Typography>\n ) : null}\n <FormControlLabel\n control={\n <Checkbox\n checked={draft.confirmed}\n onChange={(event) => change({ confirmed: event.target.checked })}\n disabled={disabled || errors.length > 0}\n />\n }\n label={OUTREACH_CURATION_CONFIRMATION_LABEL}\n />\n <Stack direction=\"row\" spacing={1}>\n <Button\n size=\"small\"\n variant=\"contained\"\n disabled={disabled || !outreachDraftUsable(draft)}\n onClick={() => change({ decision: 'use' })}\n >\n Use this\n </Button>\n <Button size=\"small\" disabled={disabled} onClick={() => change({ decision: 'keep' })}>\n Keep the template\n </Button>\n </Stack>\n </Stack>\n </Paper>\n )\n}\nOutreachCuratedStepEditor.displayName = 'OutreachCuratedStepEditor'\n\nexport default OutreachCuratedStepEditor\n"],"names":["Alert","Button","Checkbox","Chip","FormControlLabel","Paper","Stack","TextField","Typography","useMemo","isInThreadEmailStep","validateOutreachCuratedStep","OUTREACH_CURATION_CONFIRMATION_LABEL","outreachDraftState","draft","steps","source","audit","startsThread","stepIndex","subject","body","original","confirmed","decision","prompt","model","outreachMemberDraftStates","stepIndexes","flatMap","step","kind","templateId","outreachDraftToOverride","edited","outreachDraftIssues","undefined","outreachDraftUsable","some","issue","severity","OutreachCuratedStepEditor","props","label","onChange","disabled","issues","errors","filter","warnings","change","next","who","variant","sx","p","aria-label","useFlexGap","direction","spacing","alignItems","flexWrap","rowGap","flexGrow","size","color","onClick","value","event","target","fullWidth","error","path","endsWith","multiline","minRows","helperText","length","component","m","pl","map","li","message","code","join","control","checked","displayName"],"mappings":"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"}
|
|
@@ -414,6 +414,9 @@ const STATUS_COLORS = {
|
|
|
414
414
|
value: tab,
|
|
415
415
|
onChange: (_event, next)=>setTab(next),
|
|
416
416
|
"aria-label": "Where the people come from",
|
|
417
|
+
variant: "scrollable",
|
|
418
|
+
scrollButtons: "auto",
|
|
419
|
+
allowScrollButtonsMobile: true,
|
|
417
420
|
children: [
|
|
418
421
|
/*#__PURE__*/ _jsx(Tab, {
|
|
419
422
|
value: "view",
|
|
@@ -507,6 +510,7 @@ const STATUS_COLORS = {
|
|
|
507
510
|
})
|
|
508
511
|
}) : null,
|
|
509
512
|
pickedLeads.size ? /*#__PURE__*/ _jsx(Stack, {
|
|
513
|
+
useFlexGap: true,
|
|
510
514
|
direction: "row",
|
|
511
515
|
spacing: 1,
|
|
512
516
|
sx: {
|
|
@@ -584,6 +588,7 @@ const STATUS_COLORS = {
|
|
|
584
588
|
})
|
|
585
589
|
}) : null,
|
|
586
590
|
picked.size ? /*#__PURE__*/ _jsx(Stack, {
|
|
591
|
+
useFlexGap: true,
|
|
587
592
|
direction: "row",
|
|
588
593
|
spacing: 1,
|
|
589
594
|
sx: {
|
|
@@ -903,6 +908,7 @@ function PersonRow(props) {
|
|
|
903
908
|
})
|
|
904
909
|
}) : null,
|
|
905
910
|
/*#__PURE__*/ _jsxs(Stack, {
|
|
911
|
+
useFlexGap: true,
|
|
906
912
|
direction: "row",
|
|
907
913
|
spacing: 1,
|
|
908
914
|
sx: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../../../libs/plugins/outreach/src/lib/components/enroll-dialog.tsx"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n'use client'\n\nimport { pluginDocsHelp } from '@aglyn/aglyn'\nimport { HelpTip } from '@aglyn/shared-ui-jsx'\nimport {\n Alert,\n Button,\n Checkbox,\n Chip,\n type ChipProps,\n Dialog,\n DialogActions,\n DialogContent,\n DialogTitle,\n FormControlLabel,\n FormGroup,\n List,\n ListItem,\n ListItemButton,\n ListItemIcon,\n ListItemText,\n MenuItem,\n Paper,\n Stack,\n Tab,\n Tabs,\n TextField,\n Typography,\n useMediaQuery,\n useTheme,\n} from '@mui/material'\nimport { useMemo, useState } from 'react'\nimport { isOutreachGatewayFronted, outreachGatewayChip } from '../engine/mail-gateway'\nimport {\n OUTREACH_ENROLL_BATCH_MAX,\n type OutreachEnrollGateway,\n type OutreachEnrollOutcome,\n type OutreachEnrollPreviewPerson,\n type OutreachEnrollPreviewResponse,\n type OutreachEnrollPreviewStatus,\n type OutreachEnrollSource,\n type OutreachPreviewResponse,\n type OutreachStepTestResponse,\n} from '../model/outreach-api'\nimport {\n OUTREACH_ATTESTATION_LABELS,\n OUTREACH_PERSONAL_LINE_MAX,\n type OutreachAttestationKind,\n type OutreachSequence,\n type OutreachSequenceStep,\n} from '../model/outreach.types'\nimport { outreachStepName } from '../model/enrollment-timeline'\nimport { outreachEmailStepLabel } from './curate-step-dialog'\nimport {\n OutreachCuratedStepEditor,\n outreachDraftState,\n outreachDraftToOverride,\n outreachMemberDraftStates,\n type OutreachCuratedDraftState,\n} from './curated-step-editor'\nimport { OutreachLoading, OutreachLoadProblem } from './outreach-ui'\nimport type { OutreachApi } from './use-outreach-api'\nimport {\n type OutreachContactOption,\n useOutreachContactSearch,\n useOutreachLeadSearch,\n useOutreachSavedViews,\n} from './use-outreach-crm'\n\nexport interface OutreachEnrollDialogProps {\n open: boolean\n onClose(): void\n orgId: string\n sequence: OutreachSequence\n /** The consent group of the sequence's site: whose names a search shows. */\n contactGroupId: string\n uid: string | null\n api: OutreachApi\n}\n\nconst STATUS_LABELS: Record<OutreachEnrollPreviewStatus, string> = {\n eligible: 'Eligible',\n needs_confirmation: 'Needs you',\n blocked: 'Blocked',\n}\n\nconst STATUS_COLORS: Record<OutreachEnrollPreviewStatus, ChipProps['color']> = {\n eligible: 'success',\n needs_confirmation: 'warning',\n blocked: 'default',\n}\n\n/** The gateway chip's color by its tone (AGL-3326). */\nconst GATEWAY_TONE_COLORS: Record<NonNullable<ReturnType<typeof outreachGatewayChip>>['tone'], ChipProps['color']> = {\n refused: 'error',\n delivered: 'success',\n neutral: 'default',\n blocked: 'default',\n}\n\n/**\n * Whether the gateway in front of this person refused the sender this week\n * (AGL-3326): the person is shown, and left un-ticked, rather than blocked\n * — the founder decides, and ticking them is the decision.\n */\nexport function outreachGatewayRefusedThisWeek(gateway: OutreachEnrollGateway | null | undefined): boolean {\n return (gateway?.blocked7 ?? 0) > 0\n}\n\n/** Where one person's curated drafts stand (AGL-3324). */\ntype Curation =\n | { status: 'idle' }\n | { status: 'drafting' }\n | { status: 'failed'; message: string }\n | { status: 'ready' }\n\n/** What the rep has supplied for one person. */\ninterface Supplied {\n include: boolean\n personalLine: string\n attestations: OutreachAttestationKind[]\n /** The email steps drafted for this person, by step index; absent until they curate. */\n drafts?: Record<number, OutreachCuratedDraftState>\n curation?: Curation\n}\n\n/**\n * The drafts for the steps that will run: none before the step the\n * enrollment begins at (AGL-3228), which is skipped and never sent.\n */\nfunction liveDrafts(supplied: Supplied | undefined, startStepIndex: number): OutreachCuratedDraftState[] {\n return Object.values(supplied?.drafts ?? {}).filter((draft) => draft.stepIndex >= startStepIndex)\n}\n\n/** The drafts the rep used, as the enroll and the preview carry them. */\nfunction usedOverrides(supplied: Supplied | undefined, startStepIndex: number) {\n return liveDrafts(supplied, startStepIndex)\n .map(outreachDraftToOverride)\n .filter((override): override is NonNullable<typeof override> => override !== null)\n}\n\n/** Whether a drafted step is still waiting on the rep to use it or keep the template. */\nfunction hasOpenDrafts(supplied: Supplied | undefined, startStepIndex: number): boolean {\n return liveDrafts(supplied, startStepIndex).some((draft) => draft.decision === 'pending')\n}\n\n/**\n * The steps the dialog offers to begin at (AGL-3228), each by its place in\n * the sequence: \"Email 2 · step 3\", \"Step 2 · LinkedIn\".\n */\nexport function outreachStartStepOptions(\n steps: readonly OutreachSequenceStep[],\n): Array<{ value: number; label: string }> {\n return steps.map((_step, index) => ({\n value: index,\n label: index === 0 ? `${outreachStepName(steps, 0)} — from the start` : outreachStepName(steps, index),\n }))\n}\n\n/** What beginning at a later step does, as the dialog says it under the picker. */\nexport function outreachStartStepHelp(startStepIndex: number): string {\n if (startStepIndex < 1) return 'Everyone starts at step 1, after its delay.'\n const skipped = startStepIndex === 1 ? 'Step 1 is' : `Steps 1–${startStepIndex} are`\n return `For people who already had the earlier steps by hand. ${skipped} marked skipped and never sent; step ${startStepIndex + 1} goes out after its own delay, counted from now, and starts the email thread.`\n}\n\n/** Where one person's test send stands (AGL-3325). */\ntype StepTest =\n | { status: 'sending' }\n | { status: 'sent'; answer: OutreachStepTestResponse }\n | { status: 'failed'; message: string }\n\ntype Stage =\n | { kind: 'source' }\n | { kind: 'previewing' }\n | { kind: 'preview'; answer: OutreachEnrollPreviewResponse }\n | { kind: 'enrolling'; answer: OutreachEnrollPreviewResponse }\n | { kind: 'done'; results: OutreachEnrollOutcome[]; enrolled: number }\n\n/** Whether a person may be sent to Confirm as the rep has left them. */\nexport function outreachPersonReady(\n person: OutreachEnrollPreviewPerson,\n supplied: Supplied | undefined,\n startStepIndex = 0,\n): boolean {\n if (person.status === 'blocked' || !supplied?.include) return false\n const line = supplied.personalLine.trim()\n if (line.length > OUTREACH_PERSONAL_LINE_MAX) return false\n // A draft the rep has read but neither used nor kept holds them back\n // (AGL-3324): nothing is enrolled with a decision still open.\n if (hasOpenDrafts(supplied, startStepIndex)) return false\n if (person.status === 'eligible') return true\n if (person.requires.personalLine && !line) return false\n return person.requires.attestations.every((kind) =>\n supplied.attestations.includes(kind),\n )\n}\n\n/**\n * Enroll people in a sequence (AGL-2980).\n *\n * The rep picks a saved Contacts view or searches for people, and sees each\n * marked as the gates see them: eligible, blocked with the reason, or\n * waiting on them — for a cold contact, a personal line and the three\n * attestations only they can make, stored on the enrollment with who ticked\n * them and when. Enroll sends only the people who are ready, and the server\n * checks every gate again as it enrolls them.\n */\nexport function OutreachEnrollDialog(props: OutreachEnrollDialogProps) {\n const { orgId, sequence, api } = props\n const theme = useTheme()\n const narrow = useMediaQuery(theme.breakpoints.down('sm'))\n const [tab, setTab] = useState<'view' | 'search' | 'leads'>('view')\n const [viewId, setViewId] = useState('')\n const [text, setText] = useState('')\n const [picked, setPicked] = useState<Map<string, OutreachContactOption>>(\n new Map(),\n )\n // The leads picked from the sequence's site (AGL-3234), kept apart from\n // the contacts: the two are different records and the source names which.\n const [leadText, setLeadText] = useState('')\n const [pickedLeads, setPickedLeads] = useState<Map<string, OutreachContactOption>>(\n new Map(),\n )\n const [stage, setStage] = useState<Stage>({ kind: 'source' })\n const [problem, setProblem] = useState<string | null>(null)\n const [supplied, setSupplied] = useState<Record<string, Supplied>>({})\n const [emailPreview, setEmailPreview] = useState<\n Record<\n string,\n | { status: 'loading' }\n | { status: 'ready'; answer: OutreachPreviewResponse }\n | { status: 'failed'; message: string }\n >\n >({})\n const [stepTests, setStepTests] = useState<Record<string, StepTest>>({})\n // The step everyone in this enrollment begins at (AGL-3228), zero-based.\n const [startStepIndex, setStartStepIndex] = useState(0)\n const startOptions = useMemo(() => outreachStartStepOptions(sequence.steps), [sequence.steps])\n\n const views = useOutreachSavedViews(props.open ? orgId : null, props.uid)\n const search = useOutreachContactSearch({\n orgId: props.open && tab === 'search' ? orgId : null,\n hostId: sequence.hostId,\n contactGroupId: props.contactGroupId,\n text,\n })\n const leadSearch = useOutreachLeadSearch({\n // The lead silo is the org's (AGL-3275); the site still narrows it.\n orgId,\n hostId: sequence.hostId,\n text: leadText,\n enabled: props.open && tab === 'leads',\n })\n\n const reset = () => {\n setStage({ kind: 'source' })\n setProblem(null)\n setSupplied({})\n setEmailPreview({})\n setStepTests({})\n setStartStepIndex(0)\n }\n const close = () => {\n reset()\n setPicked(new Map())\n setPickedLeads(new Map())\n setText('')\n setLeadText('')\n setViewId('')\n props.onClose()\n }\n\n const preview = async (source: OutreachEnrollSource) => {\n setProblem(null)\n setStage({ kind: 'previewing' })\n try {\n const answer = await api.previewEnrollment(sequence.id, source)\n setSupplied(\n Object.fromEntries(\n answer.people.map((person) => [\n person.personId,\n {\n // A person whose gateway refused the sender this week starts\n // un-ticked (AGL-3326); the chip beside them says why.\n include: person.status !== 'blocked' && !outreachGatewayRefusedThisWeek(person.gateway),\n personalLine: '',\n attestations: [],\n },\n ]),\n ),\n )\n setStage({ kind: 'preview', answer })\n } catch (error) {\n setProblem((error as Error).message)\n setStage({ kind: 'source' })\n }\n }\n\n const answer =\n stage.kind === 'preview' || stage.kind === 'enrolling' ? stage.answer : null\n const ready = useMemo(\n () =>\n answer\n ? answer.people.filter((person) =>\n outreachPersonReady(person, supplied[person.personId], startStepIndex),\n )\n : [],\n [answer, supplied, startStepIndex],\n )\n const waiting = answer\n ? answer.people.filter(\n (person) =>\n person.status !== 'blocked' &&\n supplied[person.personId]?.include &&\n !outreachPersonReady(person, supplied[person.personId], startStepIndex),\n ).length\n : 0\n\n const enroll = async () => {\n if (!answer || !ready.length) return\n setProblem(null)\n setStage({ kind: 'enrolling', answer })\n try {\n const result = await api.enroll(\n sequence.id,\n ready.map((person) => ({\n // A contact by id, or a lead by its key (AGL-3234).\n ...(person.target === 'lead' && person.leadId\n ? { leadId: person.leadId }\n : { contactId: person.contactId }),\n personalLine: supplied[person.personId]?.personalLine.trim() ?? '',\n attestations: supplied[person.personId]?.attestations ?? [],\n // The steps they curated and confirmed (AGL-3324); nothing else.\n ...(usedOverrides(supplied[person.personId], startStepIndex).length\n ? { stepOverrides: usedOverrides(supplied[person.personId], startStepIndex) }\n : {}),\n })),\n // Named only when it is not the first step (AGL-3228).\n ...(startStepIndex > 0 ? [startStepIndex] : []),\n )\n setStage({\n kind: 'done',\n results: result.results,\n enrolled: result.enrolled,\n })\n } catch (error) {\n setProblem((error as Error).message)\n setStage({ kind: 'preview', answer })\n }\n }\n\n const supply = (personId: string, next: Partial<Supplied>) =>\n setSupplied((previous) => ({\n ...previous,\n [personId]: { ...previous[personId], ...next } as Supplied,\n }))\n\n const previewEmail = async (person: OutreachEnrollPreviewPerson) => {\n setEmailPreview((previous) => ({\n ...previous,\n [person.personId]: { status: 'loading' },\n }))\n try {\n const overrides = usedOverrides(supplied[person.personId], startStepIndex)\n const result = await api.previewEmail({\n sequenceId: sequence.id,\n ...(person.target === 'lead' && person.leadId\n ? { leadId: person.leadId }\n : { contactId: person.contactId }),\n personalLine: supplied[person.personId]?.personalLine.trim() ?? '',\n // The preview shows the curated version (AGL-3324).\n ...(overrides.length ? { stepOverrides: overrides } : {}),\n // And the first email sent from where they begin (AGL-3228).\n ...(startStepIndex > 0 ? { startStepIndex } : {}),\n })\n setEmailPreview((previous) => ({\n ...previous,\n [person.personId]: { status: 'ready', answer: result },\n }))\n } catch (error) {\n setEmailPreview((previous) => ({\n ...previous,\n [person.personId]: {\n status: 'failed',\n message: (error as Error).message,\n },\n }))\n }\n }\n\n /**\n * Curate for this person (AGL-3324): every email step drafted from their\n * record, the sequence's steps and the personal line as written so far,\n * shown under them for the rep to edit and confirm. Nothing is stored\n * until Enroll carries the drafts they used.\n */\n const curate = async (person: OutreachEnrollPreviewPerson) => {\n supply(person.personId, { curation: { status: 'drafting' } })\n try {\n const answer = await api.curateDrafts({\n sequenceId: sequence.id,\n ...(person.target === 'lead' && person.leadId\n ? { leadId: person.leadId }\n : { contactId: person.contactId }),\n personalLine: supplied[person.personId]?.personalLine.trim() ?? '',\n })\n const audit = { prompt: answer.prompt, model: answer.model }\n supply(person.personId, {\n curation: { status: 'ready' },\n drafts: Object.fromEntries(\n answer.drafts.map((draft) => [draft.stepIndex, outreachDraftState(draft, sequence.steps, 'ai', audit)]),\n ),\n })\n } catch (error) {\n supply(person.personId, { curation: { status: 'failed', message: (error as Error).message } })\n }\n }\n\n /** The rep's own words for every email step, when the AI cannot draft. */\n const writeThemselves = (person: OutreachEnrollPreviewPerson) => {\n const stepIndexes = sequence.steps\n .map((step, index) => (step.kind === 'email' ? index : -1))\n .filter((index) => index >= 0)\n supply(person.personId, {\n curation: { status: 'ready' },\n drafts: Object.fromEntries(\n outreachMemberDraftStates(sequence.steps, stepIndexes).map((draft) => [draft.stepIndex, draft]),\n ),\n })\n }\n\n /**\n * This person's first email, sent to the member as a test (AGL-3325):\n * their record, the personal line as written so far and the curated copy\n * they used (AGL-3324) fill it, and nothing is enrolled or stored for\n * them.\n */\n const sendTest = async (person: OutreachEnrollPreviewPerson) => {\n setStepTests((previous) => ({ ...previous, [person.personId]: { status: 'sending' } }))\n try {\n const overrides = usedOverrides(supplied[person.personId], startStepIndex)\n const answer = await api.sendStepTest({\n sequenceId: sequence.id,\n ...(person.target === 'lead' && person.leadId\n ? { leadId: person.leadId }\n : { contactId: person.contactId }),\n personalLine: supplied[person.personId]?.personalLine.trim() ?? '',\n ...(overrides.length ? { stepOverrides: overrides } : {}),\n ...(startStepIndex > 0 ? { startStepIndex } : {}),\n })\n setStepTests((previous) => ({ ...previous, [person.personId]: { status: 'sent', answer } }))\n } catch (error) {\n setStepTests((previous) => ({\n ...previous,\n [person.personId]: { status: 'failed', message: (error as Error).message },\n }))\n }\n }\n\n const title = `Enroll people in ${sequence.name}`\n\n return (\n <Dialog\n open={props.open}\n onClose={close}\n fullWidth\n maxWidth=\"md\"\n fullScreen={narrow}\n aria-label={title}\n >\n <DialogTitle>\n <Stack direction=\"row\" spacing={0.5} sx={{ alignItems: 'center' }}>\n <span>{title}</span>\n <HelpTip {...pluginDocsHelp('sequences', { anchor: '#enroll' })} />\n </Stack>\n </DialogTitle>\n <DialogContent dividers>\n <Stack spacing={2}>\n {problem ? <Alert severity=\"error\">{problem}</Alert> : null}\n\n {stage.kind === 'source' ? (\n <>\n <Tabs\n value={tab}\n onChange={(_event, next) => setTab(next)}\n aria-label=\"Where the people come from\"\n >\n <Tab value=\"view\" label=\"Saved view\" />\n <Tab value=\"search\" label=\"Search\" />\n <Tab value=\"leads\" label=\"Leads\" />\n </Tabs>\n {tab === 'view' ? (\n views.status === 'loading' ? (\n <OutreachLoading label=\"Loading saved views…\" />\n ) : views.status === 'error' || views.status === 'refused' ? (\n <OutreachLoadProblem\n status={views.status}\n what=\"saved views\"\n message={\n views.status === 'refused'\n ? 'Enrolling reads your CRM’s contacts, and your role does not include Manage data.'\n : null\n }\n />\n ) : views.data.length ? (\n <TextField\n select\n label=\"Saved Contacts view\"\n value={viewId}\n onChange={(event) => setViewId(event.target.value)}\n helperText={`Enrolls up to ${OUTREACH_ENROLL_BATCH_MAX} of the people the view shows at this sequence’s site — a Contacts view, or a Leads view of the site’s leads.`}\n fullWidth\n >\n {views.data.map((view) => (\n <MenuItem key={view.id} value={view.id}>\n {view.section === 'leads' ? `${view.name} (Leads)` : view.name}\n </MenuItem>\n ))}\n </TextField>\n ) : (\n <Alert severity=\"info\">\n You have no saved Contacts views to enroll from. Save one in\n the CRM, or search instead.\n </Alert>\n )\n ) : tab === 'leads' ? (\n <Stack spacing={1.5}>\n <TextField\n label=\"Search leads\"\n placeholder=\"A name, or an email address\"\n value={leadText}\n onChange={(event) => setLeadText(event.target.value)}\n helperText=\"The open leads at this sequence’s site. A lead is enrolled as it is, and follows itself to the contact it becomes.\"\n fullWidth\n autoFocus\n />\n {leadSearch.status === 'loading' ? (\n <OutreachLoading label=\"Reading leads…\" />\n ) : null}\n {leadSearch.status === 'error' || leadSearch.status === 'refused' ? (\n <OutreachLoadProblem\n status={leadSearch.status}\n what=\"leads\"\n message={\n leadSearch.status === 'refused'\n ? 'Enrolling reads your CRM’s leads, and your role does not include Manage data.'\n : 'The leads could not be read. Try again.'\n }\n />\n ) : null}\n {leadSearch.status === 'ready' && !leadSearch.idle && !leadSearch.data.length ? (\n <Typography variant=\"body2\" color=\"text.secondary\">\n No open leads at this sequence’s site match.\n </Typography>\n ) : null}\n {leadSearch.data.length ? (\n <List dense aria-label=\"Lead results\">\n {leadSearch.data.map((lead) => {\n const checked = pickedLeads.has(lead.id)\n return (\n <ListItem key={lead.id} disablePadding>\n <ListItemButton\n onClick={() =>\n setPickedLeads((previous) => {\n const next = new Map(previous)\n if (checked) next.delete(lead.id)\n else if (next.size < OUTREACH_ENROLL_BATCH_MAX) next.set(lead.id, lead)\n return next\n })\n }\n >\n <ListItemIcon>\n <Checkbox edge=\"start\" checked={checked} tabIndex={-1} disableRipple />\n </ListItemIcon>\n <ListItemText\n primary={lead.name || lead.email || lead.id}\n secondary={lead.email}\n />\n </ListItemButton>\n </ListItem>\n )\n })}\n </List>\n ) : null}\n {pickedLeads.size ? (\n <Stack\n direction=\"row\"\n spacing={1}\n sx={{ flexWrap: 'wrap', rowGap: 1 }}\n aria-label=\"Picked leads\"\n >\n {[...pickedLeads.values()].map((lead) => (\n <Chip\n key={lead.id}\n size=\"small\"\n label={lead.name || lead.email || lead.id}\n onDelete={() =>\n setPickedLeads((previous) => {\n const next = new Map(previous)\n next.delete(lead.id)\n return next\n })\n }\n />\n ))}\n </Stack>\n ) : null}\n </Stack>\n ) : (\n <Stack spacing={1.5}>\n <TextField\n label=\"Search contacts\"\n placeholder=\"A name, or an email address\"\n value={text}\n onChange={(event) => setText(event.target.value)}\n fullWidth\n autoFocus\n />\n {search.status === 'loading' ? (\n <OutreachLoading label=\"Searching…\" />\n ) : null}\n {search.status === 'error' || search.status === 'refused' ? (\n <OutreachLoadProblem\n status={search.status}\n what=\"contacts\"\n message={\n search.status === 'refused'\n ? 'Enrolling reads your CRM’s contacts, and your role does not include Manage data.'\n : 'The search failed. Try again.'\n }\n />\n ) : null}\n {search.status === 'ready' &&\n !search.idle &&\n !search.data.length ? (\n <Typography variant=\"body2\" color=\"text.secondary\">\n No contacts at this sequence’s site match.\n </Typography>\n ) : null}\n {search.data.length ? (\n <List dense aria-label=\"Search results\">\n {search.data.map((contact) => {\n const checked = picked.has(contact.id)\n return (\n <ListItem key={contact.id} disablePadding>\n <ListItemButton\n onClick={() =>\n setPicked((previous) => {\n const next = new Map(previous)\n if (checked) next.delete(contact.id)\n else if (\n next.size < OUTREACH_ENROLL_BATCH_MAX\n )\n next.set(contact.id, contact)\n return next\n })\n }\n >\n <ListItemIcon>\n <Checkbox\n edge=\"start\"\n checked={checked}\n tabIndex={-1}\n disableRipple\n />\n </ListItemIcon>\n <ListItemText\n primary={\n contact.name || contact.email || contact.id\n }\n secondary={contact.email}\n />\n </ListItemButton>\n </ListItem>\n )\n })}\n </List>\n ) : null}\n {picked.size ? (\n <Stack\n direction=\"row\"\n spacing={1}\n sx={{ flexWrap: 'wrap', rowGap: 1 }}\n aria-label=\"Picked\"\n >\n {[...picked.values()].map((contact) => (\n <Chip\n key={contact.id}\n size=\"small\"\n label={contact.name || contact.email || contact.id}\n onDelete={() =>\n setPicked((previous) => {\n const next = new Map(previous)\n next.delete(contact.id)\n return next\n })\n }\n />\n ))}\n </Stack>\n ) : null}\n </Stack>\n )}\n </>\n ) : null}\n\n {stage.kind === 'previewing' ? (\n <OutreachLoading label=\"Checking each person…\" />\n ) : null}\n\n {answer ? (\n <Stack spacing={1.5}>\n <Typography variant=\"body2\" color=\"text.secondary\">\n {summary(answer)}\n </Typography>\n {answer.truncated ? (\n <Alert severity=\"info\">\n {`This shows the first ${answer.people.length} of ${answer.total}. Enroll these, then preview again for the rest.`}\n </Alert>\n ) : null}\n {startOptions.length > 1 ? (\n <TextField\n select\n size=\"small\"\n label=\"Start at\"\n value={startStepIndex}\n onChange={(event) => {\n setStartStepIndex(Number(event.target.value))\n // A preview or a test was written for the old first email.\n setEmailPreview({})\n setStepTests({})\n }}\n helperText={outreachStartStepHelp(startStepIndex)}\n disabled={stage.kind === 'enrolling'}\n fullWidth\n >\n {startOptions.map((option) => (\n <MenuItem key={option.value} value={option.value}>\n {option.label}\n </MenuItem>\n ))}\n </TextField>\n ) : null}\n <Stack\n spacing={1}\n component=\"ul\"\n sx={{ listStyle: 'none', p: 0, m: 0 }}\n aria-label=\"People\"\n >\n {answer.people.map((person) => (\n <PersonRow\n key={person.personId}\n person={person}\n steps={sequence.steps}\n startStepIndex={startStepIndex}\n supplied={supplied[person.personId]}\n onSupply={(next) => supply(person.personId, next)}\n emailPreview={emailPreview[person.personId]}\n onPreviewEmail={() => void previewEmail(person)}\n stepTest={stepTests[person.personId]}\n onSendTest={() => void sendTest(person)}\n onCurate={() => void curate(person)}\n onWriteThemselves={() => writeThemselves(person)}\n disabled={stage.kind === 'enrolling'}\n />\n ))}\n </Stack>\n {waiting ? (\n <Typography variant=\"body2\" color=\"text.secondary\">\n {`${waiting} ${waiting === 1 ? 'person still needs' : 'people still need'} a personal line or a confirmation, or a decision on a draft, and won't be enrolled until they have one.`}\n </Typography>\n ) : null}\n </Stack>\n ) : null}\n\n {stage.kind === 'done' ? (\n <DoneSummary results={stage.results} enrolled={stage.enrolled} />\n ) : null}\n </Stack>\n </DialogContent>\n <DialogActions>\n {stage.kind === 'done' ? (\n <Button variant=\"contained\" onClick={close}>\n Done\n </Button>\n ) : (\n <>\n <Button onClick={close}>Cancel</Button>\n {stage.kind === 'preview' || stage.kind === 'enrolling' ? (\n <>\n <Button onClick={reset} disabled={stage.kind === 'enrolling'}>\n Back\n </Button>\n <Button\n variant=\"contained\"\n disabled={!ready.length || stage.kind === 'enrolling'}\n onClick={() => void enroll()}\n >\n {stage.kind === 'enrolling'\n ? 'Enrolling…'\n : `Enroll ${ready.length} ${ready.length === 1 ? 'person' : 'people'}`}\n </Button>\n </>\n ) : (\n <Button\n variant=\"contained\"\n disabled={\n stage.kind === 'previewing' ||\n (tab === 'view' ? !viewId : tab === 'leads' ? !pickedLeads.size : !picked.size)\n }\n onClick={() =>\n void preview(\n tab === 'view'\n ? { kind: 'view', viewId }\n : tab === 'leads'\n ? { kind: 'leads', leadIds: [...pickedLeads.keys()] }\n : { kind: 'contacts', contactIds: [...picked.keys()] },\n )\n }\n >\n Check people\n </Button>\n )}\n </>\n )}\n </DialogActions>\n </Dialog>\n )\n}\nOutreachEnrollDialog.displayName = 'OutreachEnrollDialog'\n\nfunction summary(answer: OutreachEnrollPreviewResponse): string {\n const count = (status: OutreachEnrollPreviewStatus) =>\n answer.people.filter((person) => person.status === status).length\n // The people behind a security gateway (AGL-3326): a Barracuda, a\n // Proofpoint or a Mimecast refuses a sender for a whole company, and a\n // LinkedIn note first is the cheaper first touch there.\n const fronted = answer.people.filter(\n (person) => person.status !== 'blocked' && isOutreachGatewayFronted(person.gateway?.gateway),\n ).length\n return (\n `${count('eligible')} eligible · ${count('needs_confirmation')} need you · ${count('blocked')} blocked` +\n (fronted ? ` · ${fronted} gateway-fronted — LinkedIn-first?` : '')\n )\n}\n\n/** The Check-people chip for one person's mail gateway (AGL-3326), or nothing. */\nfunction GatewayChip(props: { gateway: OutreachEnrollGateway | null; name: string }) {\n const chip = outreachGatewayChip(props.gateway)\n if (!chip) return null\n return (\n <Chip\n size=\"small\"\n variant={chip.tone === 'neutral' ? 'outlined' : 'filled'}\n color={GATEWAY_TONE_COLORS[chip.tone]}\n label={chip.label}\n aria-label={`Mail gateway for ${props.name}: ${chip.label}`}\n />\n )\n}\n\nfunction PersonRow(props: {\n person: OutreachEnrollPreviewPerson\n steps: readonly OutreachSequenceStep[]\n /** The step the enrollment begins at (AGL-3228); drafts before it are not shown. */\n startStepIndex: number\n supplied: Supplied | undefined\n onSupply(next: Partial<Supplied>): void\n emailPreview:\n | { status: 'loading' }\n | { status: 'ready'; answer: OutreachPreviewResponse }\n | { status: 'failed'; message: string }\n | undefined\n onPreviewEmail(): void\n stepTest: StepTest | undefined\n onSendTest(): void\n onCurate(): void\n onWriteThemselves(): void\n disabled: boolean\n}) {\n const { person, supplied, disabled } = props\n const name = person.name || person.email || person.personId\n const line = supplied?.personalLine ?? ''\n const tooLong = line.trim().length > OUTREACH_PERSONAL_LINE_MAX\n const curation = supplied?.curation ?? { status: 'idle' }\n const drafts = liveDrafts(supplied, props.startStepIndex).sort((a, b) => a.stepIndex - b.stepIndex)\n const usedCount = drafts.filter((draft) => draft.decision === 'use').length\n return (\n <Paper component=\"li\" variant=\"outlined\" sx={{ p: 1.5 }} aria-label={name}>\n <Stack spacing={1}>\n <Stack\n direction={{ xs: 'column', sm: 'row' }}\n spacing={1}\n sx={{ alignItems: { sm: 'center' } }}\n >\n <Stack sx={{ flexGrow: 1, minWidth: 0 }}>\n <Typography variant=\"body2\">{name}</Typography>\n {person.email && person.email !== name ? (\n <Typography variant=\"caption\" color=\"text.secondary\">\n {person.email}\n </Typography>\n ) : null}\n </Stack>\n <Stack direction=\"row\" spacing={1} sx={{ alignItems: 'center' }}>\n {person.target === 'lead' ? (\n <Chip size=\"small\" variant=\"outlined\" label=\"Lead\" />\n ) : null}\n {person.cold ? (\n <Chip size=\"small\" variant=\"outlined\" label=\"Cold\" />\n ) : null}\n <GatewayChip gateway={person.gateway} name={name} />\n <Chip\n size=\"small\"\n label={STATUS_LABELS[person.status]}\n color={STATUS_COLORS[person.status]}\n />\n </Stack>\n </Stack>\n {person.status === 'blocked' ? (\n <Stack component=\"ul\" spacing={0.5} sx={{ m: 0, pl: 2.5 }}>\n {person.blocks.map((block) => (\n <Typography\n key={block.code}\n component=\"li\"\n variant=\"body2\"\n color=\"text.secondary\"\n >\n {block.reason}\n </Typography>\n ))}\n </Stack>\n ) : (\n <Stack spacing={1}>\n <FormControlLabel\n control={\n <Checkbox\n checked={supplied?.include ?? true}\n onChange={(event) =>\n props.onSupply({ include: event.target.checked })\n }\n disabled={disabled}\n />\n }\n label=\"Enroll this person\"\n />\n {supplied?.include === false && outreachGatewayRefusedThisWeek(person.gateway) ? (\n <Typography variant=\"caption\" color=\"text.secondary\">\n {`Left un-ticked: their mail gateway refused ${person.gateway?.blocked7 === 1 ? 'an email' : `${person.gateway?.blocked7} emails`} from this organization this week. Tick them to enroll anyway${person.gateway?.hold ? ' — the email will go, and it is your call' : ''}.`}\n </Typography>\n ) : null}\n {supplied?.include === false ? null : (\n <>\n <TextField\n label={\n person.requires.personalLine\n ? 'Personal line'\n : 'Personal line (optional)'\n }\n placeholder=\"One sentence on why you're writing to this person now.\"\n value={line}\n onChange={(event) =>\n props.onSupply({ personalLine: event.target.value })\n }\n disabled={disabled}\n required={person.requires.personalLine}\n error={tooLong}\n helperText={\n tooLong\n ? `Keep it to one sentence, under ${OUTREACH_PERSONAL_LINE_MAX} characters.`\n : 'Goes where the emails say {{enrollment.personalLine}}.'\n }\n fullWidth\n size=\"small\"\n />\n {person.requires.attestations.length ? (\n <FormGroup aria-label={`What you confirm about ${name}`}>\n {person.requires.attestations.map((kind) => (\n <FormControlLabel\n key={kind}\n control={\n <Checkbox\n checked={\n supplied?.attestations.includes(kind) ?? false\n }\n onChange={(event) =>\n props.onSupply({\n attestations: event.target.checked\n ? [...(supplied?.attestations ?? []), kind]\n : (supplied?.attestations ?? []).filter(\n (entry) => entry !== kind,\n ),\n })\n }\n disabled={disabled}\n />\n }\n label={OUTREACH_ATTESTATION_LABELS[kind]}\n />\n ))}\n </FormGroup>\n ) : null}\n <Stack direction=\"row\" spacing={1} sx={{ flexWrap: 'wrap', rowGap: 1 }}>\n <Button\n size=\"small\"\n onClick={props.onPreviewEmail}\n disabled={disabled}\n >\n Preview the first email\n </Button>\n <Button\n size=\"small\"\n onClick={props.onSendTest}\n disabled={disabled || props.stepTest?.status === 'sending'}\n >\n {props.stepTest?.status === 'sending' ? 'Sending…' : 'Send me this as a test'}\n </Button>\n <Button\n size=\"small\"\n onClick={props.onCurate}\n disabled={disabled || curation.status === 'drafting'}\n >\n {drafts.length ? 'Curate again' : 'Curate for this person'}\n </Button>\n </Stack>\n {props.stepTest?.status === 'failed' ? (\n <Alert severity=\"error\">{props.stepTest.message}</Alert>\n ) : null}\n {props.stepTest?.status === 'sent' ? (\n <Alert severity=\"success\">\n {`Sent to ${props.stepTest.answer.sentTo} as “${props.stepTest.answer.subject}”. ${name} was not enrolled.`}\n </Alert>\n ) : null}\n {curation.status === 'drafting' ? (\n <OutreachLoading label=\"Drafting their emails…\" />\n ) : null}\n {curation.status === 'failed' ? (\n <Stack spacing={1}>\n <Alert severity=\"warning\">{curation.message}</Alert>\n <Stack direction=\"row\">\n <Button size=\"small\" onClick={props.onWriteThemselves} disabled={disabled}>\n Write them yourself\n </Button>\n </Stack>\n </Stack>\n ) : null}\n {drafts.length ? (\n <Stack spacing={1} aria-label={`Curated emails for ${name}`}>\n <Typography variant=\"caption\" color=\"text.secondary\">\n {usedCount\n ? `${usedCount} of ${drafts.length} ${drafts.length === 1 ? 'email' : 'emails'} curated for ${name}. Nothing is sent that you haven't confirmed.`\n : `Their emails, rewritten for them. Read each one, edit it, and use it or keep the template.`}\n </Typography>\n {drafts.map((draft) => (\n <OutreachCuratedStepEditor\n key={draft.stepIndex}\n draft={draft}\n label={outreachEmailStepLabel(props.steps, draft.stepIndex)}\n onChange={(next) =>\n props.onSupply({ drafts: { ...(supplied?.drafts ?? {}), [next.stepIndex]: next } })\n }\n disabled={disabled}\n />\n ))}\n </Stack>\n ) : null}\n {props.emailPreview?.status === 'loading' ? (\n <OutreachLoading label=\"Writing the email…\" />\n ) : null}\n {props.emailPreview?.status === 'failed' ? (\n <Alert severity=\"error\">{props.emailPreview.message}</Alert>\n ) : null}\n {props.emailPreview?.status === 'ready' ? (\n props.emailPreview.answer.error ? (\n <Alert severity=\"info\">\n {props.emailPreview.answer.error.message}\n </Alert>\n ) : (\n <Paper\n variant=\"outlined\"\n sx={{ p: 1.5 }}\n aria-label={`First email to ${name}`}\n >\n <Typography variant=\"body2\">{`Subject: ${props.emailPreview.answer.subject}`}</Typography>\n <Typography\n variant=\"body2\"\n sx={{\n whiteSpace: 'pre-wrap',\n wordBreak: 'break-word',\n mt: 1,\n }}\n >\n {props.emailPreview.answer.text}\n </Typography>\n </Paper>\n )\n ) : null}\n </>\n )}\n </Stack>\n )}\n </Stack>\n </Paper>\n )\n}\n\nfunction DoneSummary(props: {\n results: OutreachEnrollOutcome[]\n enrolled: number\n}) {\n const refused = props.results.filter(\n (\n result,\n ): result is Extract<OutreachEnrollOutcome, { outcome: 'blocked' }> =>\n result.outcome === 'blocked',\n )\n return (\n <Stack spacing={1.5}>\n <Alert severity={props.enrolled ? 'success' : 'info'}>\n {props.enrolled\n ? `Enrolled ${props.enrolled} ${props.enrolled === 1 ? 'person' : 'people'}. Their first step goes out in the mailbox's sending hours.`\n : 'Nobody was enrolled.'}\n </Alert>\n {refused.length ? (\n <Stack spacing={1}>\n <Typography variant=\"subtitle2\">\n Not enrolled, checked again just now:\n </Typography>\n {refused.map((result) => (\n <Stack key={result.personId} spacing={0.25}>\n <Typography variant=\"body2\">\n {result.email ?? result.personId}\n </Typography>\n {result.blocks.map((block) => (\n <Typography\n key={block.code}\n variant=\"body2\"\n color=\"text.secondary\"\n >\n {block.reason}\n </Typography>\n ))}\n </Stack>\n ))}\n </Stack>\n ) : null}\n </Stack>\n )\n}\n\nexport default OutreachEnrollDialog\n"],"names":["pluginDocsHelp","HelpTip","Alert","Button","Checkbox","Chip","Dialog","DialogActions","DialogContent","DialogTitle","FormControlLabel","FormGroup","List","ListItem","ListItemButton","ListItemIcon","ListItemText","MenuItem","Paper","Stack","Tab","Tabs","TextField","Typography","useMediaQuery","useTheme","useMemo","useState","isOutreachGatewayFronted","outreachGatewayChip","OUTREACH_ENROLL_BATCH_MAX","OUTREACH_ATTESTATION_LABELS","OUTREACH_PERSONAL_LINE_MAX","outreachStepName","outreachEmailStepLabel","OutreachCuratedStepEditor","outreachDraftState","outreachDraftToOverride","outreachMemberDraftStates","OutreachLoading","OutreachLoadProblem","useOutreachContactSearch","useOutreachLeadSearch","useOutreachSavedViews","STATUS_LABELS","eligible","needs_confirmation","blocked","STATUS_COLORS","GATEWAY_TONE_COLORS","refused","delivered","neutral","outreachGatewayRefusedThisWeek","gateway","blocked7","liveDrafts","supplied","startStepIndex","Object","values","drafts","filter","draft","stepIndex","usedOverrides","map","override","hasOpenDrafts","some","decision","outreachStartStepOptions","steps","_step","index","value","label","outreachStartStepHelp","skipped","outreachPersonReady","person","status","include","line","personalLine","trim","length","requires","attestations","every","kind","includes","OutreachEnrollDialog","props","orgId","sequence","api","theme","narrow","breakpoints","down","tab","setTab","viewId","setViewId","text","setText","picked","setPicked","Map","leadText","setLeadText","pickedLeads","setPickedLeads","stage","setStage","problem","setProblem","setSupplied","emailPreview","setEmailPreview","stepTests","setStepTests","setStartStepIndex","startOptions","views","open","uid","search","hostId","contactGroupId","leadSearch","enabled","reset","close","onClose","preview","source","answer","previewEnrollment","id","fromEntries","people","personId","error","message","ready","waiting","enroll","result","target","leadId","contactId","stepOverrides","results","enrolled","supply","next","previous","previewEmail","overrides","sequenceId","curate","curation","curateDrafts","audit","prompt","model","writeThemselves","stepIndexes","step","sendTest","sendStepTest","title","name","fullWidth","maxWidth","fullScreen","aria-label","direction","spacing","sx","alignItems","span","anchor","dividers","severity","onChange","_event","what","data","select","event","helperText","view","section","placeholder","autoFocus","idle","variant","color","dense","lead","checked","has","disablePadding","onClick","delete","size","set","edge","tabIndex","disableRipple","primary","email","secondary","flexWrap","rowGap","onDelete","contact","summary","truncated","total","Number","disabled","option","component","listStyle","p","m","PersonRow","onSupply","onPreviewEmail","stepTest","onSendTest","onCurate","onWriteThemselves","DoneSummary","leadIds","keys","contactIds","displayName","count","fronted","GatewayChip","chip","tone","tooLong","sort","a","b","usedCount","xs","sm","flexGrow","minWidth","cold","pl","blocks","block","reason","code","control","hold","required","entry","sentTo","subject","whiteSpace","wordBreak","mt","outcome"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../../../../../libs/plugins/outreach/src/lib/components/enroll-dialog.tsx"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n'use client'\n\nimport { pluginDocsHelp } from '@aglyn/aglyn'\nimport { HelpTip } from '@aglyn/shared-ui-jsx'\nimport {\n Alert,\n Button,\n Checkbox,\n Chip,\n type ChipProps,\n Dialog,\n DialogActions,\n DialogContent,\n DialogTitle,\n FormControlLabel,\n FormGroup,\n List,\n ListItem,\n ListItemButton,\n ListItemIcon,\n ListItemText,\n MenuItem,\n Paper,\n Stack,\n Tab,\n Tabs,\n TextField,\n Typography,\n useMediaQuery,\n useTheme,\n} from '@mui/material'\nimport { useMemo, useState } from 'react'\nimport { isOutreachGatewayFronted, outreachGatewayChip } from '../engine/mail-gateway'\nimport {\n OUTREACH_ENROLL_BATCH_MAX,\n type OutreachEnrollGateway,\n type OutreachEnrollOutcome,\n type OutreachEnrollPreviewPerson,\n type OutreachEnrollPreviewResponse,\n type OutreachEnrollPreviewStatus,\n type OutreachEnrollSource,\n type OutreachPreviewResponse,\n type OutreachStepTestResponse,\n} from '../model/outreach-api'\nimport {\n OUTREACH_ATTESTATION_LABELS,\n OUTREACH_PERSONAL_LINE_MAX,\n type OutreachAttestationKind,\n type OutreachSequence,\n type OutreachSequenceStep,\n} from '../model/outreach.types'\nimport { outreachStepName } from '../model/enrollment-timeline'\nimport { outreachEmailStepLabel } from './curate-step-dialog'\nimport {\n OutreachCuratedStepEditor,\n outreachDraftState,\n outreachDraftToOverride,\n outreachMemberDraftStates,\n type OutreachCuratedDraftState,\n} from './curated-step-editor'\nimport { OutreachLoading, OutreachLoadProblem } from './outreach-ui'\nimport type { OutreachApi } from './use-outreach-api'\nimport {\n type OutreachContactOption,\n useOutreachContactSearch,\n useOutreachLeadSearch,\n useOutreachSavedViews,\n} from './use-outreach-crm'\n\nexport interface OutreachEnrollDialogProps {\n open: boolean\n onClose(): void\n orgId: string\n sequence: OutreachSequence\n /** The consent group of the sequence's site: whose names a search shows. */\n contactGroupId: string\n uid: string | null\n api: OutreachApi\n}\n\nconst STATUS_LABELS: Record<OutreachEnrollPreviewStatus, string> = {\n eligible: 'Eligible',\n needs_confirmation: 'Needs you',\n blocked: 'Blocked',\n}\n\nconst STATUS_COLORS: Record<OutreachEnrollPreviewStatus, ChipProps['color']> = {\n eligible: 'success',\n needs_confirmation: 'warning',\n blocked: 'default',\n}\n\n/** The gateway chip's color by its tone (AGL-3326). */\nconst GATEWAY_TONE_COLORS: Record<NonNullable<ReturnType<typeof outreachGatewayChip>>['tone'], ChipProps['color']> = {\n refused: 'error',\n delivered: 'success',\n neutral: 'default',\n blocked: 'default',\n}\n\n/**\n * Whether the gateway in front of this person refused the sender this week\n * (AGL-3326): the person is shown, and left un-ticked, rather than blocked\n * — the founder decides, and ticking them is the decision.\n */\nexport function outreachGatewayRefusedThisWeek(gateway: OutreachEnrollGateway | null | undefined): boolean {\n return (gateway?.blocked7 ?? 0) > 0\n}\n\n/** Where one person's curated drafts stand (AGL-3324). */\ntype Curation =\n | { status: 'idle' }\n | { status: 'drafting' }\n | { status: 'failed'; message: string }\n | { status: 'ready' }\n\n/** What the rep has supplied for one person. */\ninterface Supplied {\n include: boolean\n personalLine: string\n attestations: OutreachAttestationKind[]\n /** The email steps drafted for this person, by step index; absent until they curate. */\n drafts?: Record<number, OutreachCuratedDraftState>\n curation?: Curation\n}\n\n/**\n * The drafts for the steps that will run: none before the step the\n * enrollment begins at (AGL-3228), which is skipped and never sent.\n */\nfunction liveDrafts(supplied: Supplied | undefined, startStepIndex: number): OutreachCuratedDraftState[] {\n return Object.values(supplied?.drafts ?? {}).filter((draft) => draft.stepIndex >= startStepIndex)\n}\n\n/** The drafts the rep used, as the enroll and the preview carry them. */\nfunction usedOverrides(supplied: Supplied | undefined, startStepIndex: number) {\n return liveDrafts(supplied, startStepIndex)\n .map(outreachDraftToOverride)\n .filter((override): override is NonNullable<typeof override> => override !== null)\n}\n\n/** Whether a drafted step is still waiting on the rep to use it or keep the template. */\nfunction hasOpenDrafts(supplied: Supplied | undefined, startStepIndex: number): boolean {\n return liveDrafts(supplied, startStepIndex).some((draft) => draft.decision === 'pending')\n}\n\n/**\n * The steps the dialog offers to begin at (AGL-3228), each by its place in\n * the sequence: \"Email 2 · step 3\", \"Step 2 · LinkedIn\".\n */\nexport function outreachStartStepOptions(\n steps: readonly OutreachSequenceStep[],\n): Array<{ value: number; label: string }> {\n return steps.map((_step, index) => ({\n value: index,\n label: index === 0 ? `${outreachStepName(steps, 0)} — from the start` : outreachStepName(steps, index),\n }))\n}\n\n/** What beginning at a later step does, as the dialog says it under the picker. */\nexport function outreachStartStepHelp(startStepIndex: number): string {\n if (startStepIndex < 1) return 'Everyone starts at step 1, after its delay.'\n const skipped = startStepIndex === 1 ? 'Step 1 is' : `Steps 1–${startStepIndex} are`\n return `For people who already had the earlier steps by hand. ${skipped} marked skipped and never sent; step ${startStepIndex + 1} goes out after its own delay, counted from now, and starts the email thread.`\n}\n\n/** Where one person's test send stands (AGL-3325). */\ntype StepTest =\n | { status: 'sending' }\n | { status: 'sent'; answer: OutreachStepTestResponse }\n | { status: 'failed'; message: string }\n\ntype Stage =\n | { kind: 'source' }\n | { kind: 'previewing' }\n | { kind: 'preview'; answer: OutreachEnrollPreviewResponse }\n | { kind: 'enrolling'; answer: OutreachEnrollPreviewResponse }\n | { kind: 'done'; results: OutreachEnrollOutcome[]; enrolled: number }\n\n/** Whether a person may be sent to Confirm as the rep has left them. */\nexport function outreachPersonReady(\n person: OutreachEnrollPreviewPerson,\n supplied: Supplied | undefined,\n startStepIndex = 0,\n): boolean {\n if (person.status === 'blocked' || !supplied?.include) return false\n const line = supplied.personalLine.trim()\n if (line.length > OUTREACH_PERSONAL_LINE_MAX) return false\n // A draft the rep has read but neither used nor kept holds them back\n // (AGL-3324): nothing is enrolled with a decision still open.\n if (hasOpenDrafts(supplied, startStepIndex)) return false\n if (person.status === 'eligible') return true\n if (person.requires.personalLine && !line) return false\n return person.requires.attestations.every((kind) =>\n supplied.attestations.includes(kind),\n )\n}\n\n/**\n * Enroll people in a sequence (AGL-2980).\n *\n * The rep picks a saved Contacts view or searches for people, and sees each\n * marked as the gates see them: eligible, blocked with the reason, or\n * waiting on them — for a cold contact, a personal line and the three\n * attestations only they can make, stored on the enrollment with who ticked\n * them and when. Enroll sends only the people who are ready, and the server\n * checks every gate again as it enrolls them.\n */\nexport function OutreachEnrollDialog(props: OutreachEnrollDialogProps) {\n const { orgId, sequence, api } = props\n const theme = useTheme()\n const narrow = useMediaQuery(theme.breakpoints.down('sm'))\n const [tab, setTab] = useState<'view' | 'search' | 'leads'>('view')\n const [viewId, setViewId] = useState('')\n const [text, setText] = useState('')\n const [picked, setPicked] = useState<Map<string, OutreachContactOption>>(\n new Map(),\n )\n // The leads picked from the sequence's site (AGL-3234), kept apart from\n // the contacts: the two are different records and the source names which.\n const [leadText, setLeadText] = useState('')\n const [pickedLeads, setPickedLeads] = useState<Map<string, OutreachContactOption>>(\n new Map(),\n )\n const [stage, setStage] = useState<Stage>({ kind: 'source' })\n const [problem, setProblem] = useState<string | null>(null)\n const [supplied, setSupplied] = useState<Record<string, Supplied>>({})\n const [emailPreview, setEmailPreview] = useState<\n Record<\n string,\n | { status: 'loading' }\n | { status: 'ready'; answer: OutreachPreviewResponse }\n | { status: 'failed'; message: string }\n >\n >({})\n const [stepTests, setStepTests] = useState<Record<string, StepTest>>({})\n // The step everyone in this enrollment begins at (AGL-3228), zero-based.\n const [startStepIndex, setStartStepIndex] = useState(0)\n const startOptions = useMemo(() => outreachStartStepOptions(sequence.steps), [sequence.steps])\n\n const views = useOutreachSavedViews(props.open ? orgId : null, props.uid)\n const search = useOutreachContactSearch({\n orgId: props.open && tab === 'search' ? orgId : null,\n hostId: sequence.hostId,\n contactGroupId: props.contactGroupId,\n text,\n })\n const leadSearch = useOutreachLeadSearch({\n // The lead silo is the org's (AGL-3275); the site still narrows it.\n orgId,\n hostId: sequence.hostId,\n text: leadText,\n enabled: props.open && tab === 'leads',\n })\n\n const reset = () => {\n setStage({ kind: 'source' })\n setProblem(null)\n setSupplied({})\n setEmailPreview({})\n setStepTests({})\n setStartStepIndex(0)\n }\n const close = () => {\n reset()\n setPicked(new Map())\n setPickedLeads(new Map())\n setText('')\n setLeadText('')\n setViewId('')\n props.onClose()\n }\n\n const preview = async (source: OutreachEnrollSource) => {\n setProblem(null)\n setStage({ kind: 'previewing' })\n try {\n const answer = await api.previewEnrollment(sequence.id, source)\n setSupplied(\n Object.fromEntries(\n answer.people.map((person) => [\n person.personId,\n {\n // A person whose gateway refused the sender this week starts\n // un-ticked (AGL-3326); the chip beside them says why.\n include: person.status !== 'blocked' && !outreachGatewayRefusedThisWeek(person.gateway),\n personalLine: '',\n attestations: [],\n },\n ]),\n ),\n )\n setStage({ kind: 'preview', answer })\n } catch (error) {\n setProblem((error as Error).message)\n setStage({ kind: 'source' })\n }\n }\n\n const answer =\n stage.kind === 'preview' || stage.kind === 'enrolling' ? stage.answer : null\n const ready = useMemo(\n () =>\n answer\n ? answer.people.filter((person) =>\n outreachPersonReady(person, supplied[person.personId], startStepIndex),\n )\n : [],\n [answer, supplied, startStepIndex],\n )\n const waiting = answer\n ? answer.people.filter(\n (person) =>\n person.status !== 'blocked' &&\n supplied[person.personId]?.include &&\n !outreachPersonReady(person, supplied[person.personId], startStepIndex),\n ).length\n : 0\n\n const enroll = async () => {\n if (!answer || !ready.length) return\n setProblem(null)\n setStage({ kind: 'enrolling', answer })\n try {\n const result = await api.enroll(\n sequence.id,\n ready.map((person) => ({\n // A contact by id, or a lead by its key (AGL-3234).\n ...(person.target === 'lead' && person.leadId\n ? { leadId: person.leadId }\n : { contactId: person.contactId }),\n personalLine: supplied[person.personId]?.personalLine.trim() ?? '',\n attestations: supplied[person.personId]?.attestations ?? [],\n // The steps they curated and confirmed (AGL-3324); nothing else.\n ...(usedOverrides(supplied[person.personId], startStepIndex).length\n ? { stepOverrides: usedOverrides(supplied[person.personId], startStepIndex) }\n : {}),\n })),\n // Named only when it is not the first step (AGL-3228).\n ...(startStepIndex > 0 ? [startStepIndex] : []),\n )\n setStage({\n kind: 'done',\n results: result.results,\n enrolled: result.enrolled,\n })\n } catch (error) {\n setProblem((error as Error).message)\n setStage({ kind: 'preview', answer })\n }\n }\n\n const supply = (personId: string, next: Partial<Supplied>) =>\n setSupplied((previous) => ({\n ...previous,\n [personId]: { ...previous[personId], ...next } as Supplied,\n }))\n\n const previewEmail = async (person: OutreachEnrollPreviewPerson) => {\n setEmailPreview((previous) => ({\n ...previous,\n [person.personId]: { status: 'loading' },\n }))\n try {\n const overrides = usedOverrides(supplied[person.personId], startStepIndex)\n const result = await api.previewEmail({\n sequenceId: sequence.id,\n ...(person.target === 'lead' && person.leadId\n ? { leadId: person.leadId }\n : { contactId: person.contactId }),\n personalLine: supplied[person.personId]?.personalLine.trim() ?? '',\n // The preview shows the curated version (AGL-3324).\n ...(overrides.length ? { stepOverrides: overrides } : {}),\n // And the first email sent from where they begin (AGL-3228).\n ...(startStepIndex > 0 ? { startStepIndex } : {}),\n })\n setEmailPreview((previous) => ({\n ...previous,\n [person.personId]: { status: 'ready', answer: result },\n }))\n } catch (error) {\n setEmailPreview((previous) => ({\n ...previous,\n [person.personId]: {\n status: 'failed',\n message: (error as Error).message,\n },\n }))\n }\n }\n\n /**\n * Curate for this person (AGL-3324): every email step drafted from their\n * record, the sequence's steps and the personal line as written so far,\n * shown under them for the rep to edit and confirm. Nothing is stored\n * until Enroll carries the drafts they used.\n */\n const curate = async (person: OutreachEnrollPreviewPerson) => {\n supply(person.personId, { curation: { status: 'drafting' } })\n try {\n const answer = await api.curateDrafts({\n sequenceId: sequence.id,\n ...(person.target === 'lead' && person.leadId\n ? { leadId: person.leadId }\n : { contactId: person.contactId }),\n personalLine: supplied[person.personId]?.personalLine.trim() ?? '',\n })\n const audit = { prompt: answer.prompt, model: answer.model }\n supply(person.personId, {\n curation: { status: 'ready' },\n drafts: Object.fromEntries(\n answer.drafts.map((draft) => [draft.stepIndex, outreachDraftState(draft, sequence.steps, 'ai', audit)]),\n ),\n })\n } catch (error) {\n supply(person.personId, { curation: { status: 'failed', message: (error as Error).message } })\n }\n }\n\n /** The rep's own words for every email step, when the AI cannot draft. */\n const writeThemselves = (person: OutreachEnrollPreviewPerson) => {\n const stepIndexes = sequence.steps\n .map((step, index) => (step.kind === 'email' ? index : -1))\n .filter((index) => index >= 0)\n supply(person.personId, {\n curation: { status: 'ready' },\n drafts: Object.fromEntries(\n outreachMemberDraftStates(sequence.steps, stepIndexes).map((draft) => [draft.stepIndex, draft]),\n ),\n })\n }\n\n /**\n * This person's first email, sent to the member as a test (AGL-3325):\n * their record, the personal line as written so far and the curated copy\n * they used (AGL-3324) fill it, and nothing is enrolled or stored for\n * them.\n */\n const sendTest = async (person: OutreachEnrollPreviewPerson) => {\n setStepTests((previous) => ({ ...previous, [person.personId]: { status: 'sending' } }))\n try {\n const overrides = usedOverrides(supplied[person.personId], startStepIndex)\n const answer = await api.sendStepTest({\n sequenceId: sequence.id,\n ...(person.target === 'lead' && person.leadId\n ? { leadId: person.leadId }\n : { contactId: person.contactId }),\n personalLine: supplied[person.personId]?.personalLine.trim() ?? '',\n ...(overrides.length ? { stepOverrides: overrides } : {}),\n ...(startStepIndex > 0 ? { startStepIndex } : {}),\n })\n setStepTests((previous) => ({ ...previous, [person.personId]: { status: 'sent', answer } }))\n } catch (error) {\n setStepTests((previous) => ({\n ...previous,\n [person.personId]: { status: 'failed', message: (error as Error).message },\n }))\n }\n }\n\n const title = `Enroll people in ${sequence.name}`\n\n return (\n <Dialog\n open={props.open}\n onClose={close}\n fullWidth\n maxWidth=\"md\"\n fullScreen={narrow}\n aria-label={title}\n >\n <DialogTitle>\n <Stack direction=\"row\" spacing={0.5} sx={{ alignItems: 'center' }}>\n <span>{title}</span>\n <HelpTip {...pluginDocsHelp('sequences', { anchor: '#enroll' })} />\n </Stack>\n </DialogTitle>\n <DialogContent dividers>\n <Stack spacing={2}>\n {problem ? <Alert severity=\"error\">{problem}</Alert> : null}\n\n {stage.kind === 'source' ? (\n <>\n <Tabs\n value={tab}\n onChange={(_event, next) => setTab(next)}\n aria-label=\"Where the people come from\"\n variant=\"scrollable\"\n scrollButtons=\"auto\"\n allowScrollButtonsMobile\n >\n <Tab value=\"view\" label=\"Saved view\" />\n <Tab value=\"search\" label=\"Search\" />\n <Tab value=\"leads\" label=\"Leads\" />\n </Tabs>\n {tab === 'view' ? (\n views.status === 'loading' ? (\n <OutreachLoading label=\"Loading saved views…\" />\n ) : views.status === 'error' || views.status === 'refused' ? (\n <OutreachLoadProblem\n status={views.status}\n what=\"saved views\"\n message={\n views.status === 'refused'\n ? 'Enrolling reads your CRM’s contacts, and your role does not include Manage data.'\n : null\n }\n />\n ) : views.data.length ? (\n <TextField\n select\n label=\"Saved Contacts view\"\n value={viewId}\n onChange={(event) => setViewId(event.target.value)}\n helperText={`Enrolls up to ${OUTREACH_ENROLL_BATCH_MAX} of the people the view shows at this sequence’s site — a Contacts view, or a Leads view of the site’s leads.`}\n fullWidth\n >\n {views.data.map((view) => (\n <MenuItem key={view.id} value={view.id}>\n {view.section === 'leads' ? `${view.name} (Leads)` : view.name}\n </MenuItem>\n ))}\n </TextField>\n ) : (\n <Alert severity=\"info\">\n You have no saved Contacts views to enroll from. Save one in\n the CRM, or search instead.\n </Alert>\n )\n ) : tab === 'leads' ? (\n <Stack spacing={1.5}>\n <TextField\n label=\"Search leads\"\n placeholder=\"A name, or an email address\"\n value={leadText}\n onChange={(event) => setLeadText(event.target.value)}\n helperText=\"The open leads at this sequence’s site. A lead is enrolled as it is, and follows itself to the contact it becomes.\"\n fullWidth\n autoFocus\n />\n {leadSearch.status === 'loading' ? (\n <OutreachLoading label=\"Reading leads…\" />\n ) : null}\n {leadSearch.status === 'error' || leadSearch.status === 'refused' ? (\n <OutreachLoadProblem\n status={leadSearch.status}\n what=\"leads\"\n message={\n leadSearch.status === 'refused'\n ? 'Enrolling reads your CRM’s leads, and your role does not include Manage data.'\n : 'The leads could not be read. Try again.'\n }\n />\n ) : null}\n {leadSearch.status === 'ready' && !leadSearch.idle && !leadSearch.data.length ? (\n <Typography variant=\"body2\" color=\"text.secondary\">\n No open leads at this sequence’s site match.\n </Typography>\n ) : null}\n {leadSearch.data.length ? (\n <List dense aria-label=\"Lead results\">\n {leadSearch.data.map((lead) => {\n const checked = pickedLeads.has(lead.id)\n return (\n <ListItem key={lead.id} disablePadding>\n <ListItemButton\n onClick={() =>\n setPickedLeads((previous) => {\n const next = new Map(previous)\n if (checked) next.delete(lead.id)\n else if (next.size < OUTREACH_ENROLL_BATCH_MAX) next.set(lead.id, lead)\n return next\n })\n }\n >\n <ListItemIcon>\n <Checkbox edge=\"start\" checked={checked} tabIndex={-1} disableRipple />\n </ListItemIcon>\n <ListItemText\n primary={lead.name || lead.email || lead.id}\n secondary={lead.email}\n />\n </ListItemButton>\n </ListItem>\n )\n })}\n </List>\n ) : null}\n {pickedLeads.size ? (\n <Stack\n useFlexGap\n direction=\"row\"\n spacing={1}\n sx={{ flexWrap: 'wrap', rowGap: 1 }}\n aria-label=\"Picked leads\"\n >\n {[...pickedLeads.values()].map((lead) => (\n <Chip\n key={lead.id}\n size=\"small\"\n label={lead.name || lead.email || lead.id}\n onDelete={() =>\n setPickedLeads((previous) => {\n const next = new Map(previous)\n next.delete(lead.id)\n return next\n })\n }\n />\n ))}\n </Stack>\n ) : null}\n </Stack>\n ) : (\n <Stack spacing={1.5}>\n <TextField\n label=\"Search contacts\"\n placeholder=\"A name, or an email address\"\n value={text}\n onChange={(event) => setText(event.target.value)}\n fullWidth\n autoFocus\n />\n {search.status === 'loading' ? (\n <OutreachLoading label=\"Searching…\" />\n ) : null}\n {search.status === 'error' || search.status === 'refused' ? (\n <OutreachLoadProblem\n status={search.status}\n what=\"contacts\"\n message={\n search.status === 'refused'\n ? 'Enrolling reads your CRM’s contacts, and your role does not include Manage data.'\n : 'The search failed. Try again.'\n }\n />\n ) : null}\n {search.status === 'ready' &&\n !search.idle &&\n !search.data.length ? (\n <Typography variant=\"body2\" color=\"text.secondary\">\n No contacts at this sequence’s site match.\n </Typography>\n ) : null}\n {search.data.length ? (\n <List dense aria-label=\"Search results\">\n {search.data.map((contact) => {\n const checked = picked.has(contact.id)\n return (\n <ListItem key={contact.id} disablePadding>\n <ListItemButton\n onClick={() =>\n setPicked((previous) => {\n const next = new Map(previous)\n if (checked) next.delete(contact.id)\n else if (\n next.size < OUTREACH_ENROLL_BATCH_MAX\n )\n next.set(contact.id, contact)\n return next\n })\n }\n >\n <ListItemIcon>\n <Checkbox\n edge=\"start\"\n checked={checked}\n tabIndex={-1}\n disableRipple\n />\n </ListItemIcon>\n <ListItemText\n primary={\n contact.name || contact.email || contact.id\n }\n secondary={contact.email}\n />\n </ListItemButton>\n </ListItem>\n )\n })}\n </List>\n ) : null}\n {picked.size ? (\n <Stack\n useFlexGap\n direction=\"row\"\n spacing={1}\n sx={{ flexWrap: 'wrap', rowGap: 1 }}\n aria-label=\"Picked\"\n >\n {[...picked.values()].map((contact) => (\n <Chip\n key={contact.id}\n size=\"small\"\n label={contact.name || contact.email || contact.id}\n onDelete={() =>\n setPicked((previous) => {\n const next = new Map(previous)\n next.delete(contact.id)\n return next\n })\n }\n />\n ))}\n </Stack>\n ) : null}\n </Stack>\n )}\n </>\n ) : null}\n\n {stage.kind === 'previewing' ? (\n <OutreachLoading label=\"Checking each person…\" />\n ) : null}\n\n {answer ? (\n <Stack spacing={1.5}>\n <Typography variant=\"body2\" color=\"text.secondary\">\n {summary(answer)}\n </Typography>\n {answer.truncated ? (\n <Alert severity=\"info\">\n {`This shows the first ${answer.people.length} of ${answer.total}. Enroll these, then preview again for the rest.`}\n </Alert>\n ) : null}\n {startOptions.length > 1 ? (\n <TextField\n select\n size=\"small\"\n label=\"Start at\"\n value={startStepIndex}\n onChange={(event) => {\n setStartStepIndex(Number(event.target.value))\n // A preview or a test was written for the old first email.\n setEmailPreview({})\n setStepTests({})\n }}\n helperText={outreachStartStepHelp(startStepIndex)}\n disabled={stage.kind === 'enrolling'}\n fullWidth\n >\n {startOptions.map((option) => (\n <MenuItem key={option.value} value={option.value}>\n {option.label}\n </MenuItem>\n ))}\n </TextField>\n ) : null}\n <Stack\n spacing={1}\n component=\"ul\"\n sx={{ listStyle: 'none', p: 0, m: 0 }}\n aria-label=\"People\"\n >\n {answer.people.map((person) => (\n <PersonRow\n key={person.personId}\n person={person}\n steps={sequence.steps}\n startStepIndex={startStepIndex}\n supplied={supplied[person.personId]}\n onSupply={(next) => supply(person.personId, next)}\n emailPreview={emailPreview[person.personId]}\n onPreviewEmail={() => void previewEmail(person)}\n stepTest={stepTests[person.personId]}\n onSendTest={() => void sendTest(person)}\n onCurate={() => void curate(person)}\n onWriteThemselves={() => writeThemselves(person)}\n disabled={stage.kind === 'enrolling'}\n />\n ))}\n </Stack>\n {waiting ? (\n <Typography variant=\"body2\" color=\"text.secondary\">\n {`${waiting} ${waiting === 1 ? 'person still needs' : 'people still need'} a personal line or a confirmation, or a decision on a draft, and won't be enrolled until they have one.`}\n </Typography>\n ) : null}\n </Stack>\n ) : null}\n\n {stage.kind === 'done' ? (\n <DoneSummary results={stage.results} enrolled={stage.enrolled} />\n ) : null}\n </Stack>\n </DialogContent>\n <DialogActions>\n {stage.kind === 'done' ? (\n <Button variant=\"contained\" onClick={close}>\n Done\n </Button>\n ) : (\n <>\n <Button onClick={close}>Cancel</Button>\n {stage.kind === 'preview' || stage.kind === 'enrolling' ? (\n <>\n <Button onClick={reset} disabled={stage.kind === 'enrolling'}>\n Back\n </Button>\n <Button\n variant=\"contained\"\n disabled={!ready.length || stage.kind === 'enrolling'}\n onClick={() => void enroll()}\n >\n {stage.kind === 'enrolling'\n ? 'Enrolling…'\n : `Enroll ${ready.length} ${ready.length === 1 ? 'person' : 'people'}`}\n </Button>\n </>\n ) : (\n <Button\n variant=\"contained\"\n disabled={\n stage.kind === 'previewing' ||\n (tab === 'view' ? !viewId : tab === 'leads' ? !pickedLeads.size : !picked.size)\n }\n onClick={() =>\n void preview(\n tab === 'view'\n ? { kind: 'view', viewId }\n : tab === 'leads'\n ? { kind: 'leads', leadIds: [...pickedLeads.keys()] }\n : { kind: 'contacts', contactIds: [...picked.keys()] },\n )\n }\n >\n Check people\n </Button>\n )}\n </>\n )}\n </DialogActions>\n </Dialog>\n )\n}\nOutreachEnrollDialog.displayName = 'OutreachEnrollDialog'\n\nfunction summary(answer: OutreachEnrollPreviewResponse): string {\n const count = (status: OutreachEnrollPreviewStatus) =>\n answer.people.filter((person) => person.status === status).length\n // The people behind a security gateway (AGL-3326): a Barracuda, a\n // Proofpoint or a Mimecast refuses a sender for a whole company, and a\n // LinkedIn note first is the cheaper first touch there.\n const fronted = answer.people.filter(\n (person) => person.status !== 'blocked' && isOutreachGatewayFronted(person.gateway?.gateway),\n ).length\n return (\n `${count('eligible')} eligible · ${count('needs_confirmation')} need you · ${count('blocked')} blocked` +\n (fronted ? ` · ${fronted} gateway-fronted — LinkedIn-first?` : '')\n )\n}\n\n/** The Check-people chip for one person's mail gateway (AGL-3326), or nothing. */\nfunction GatewayChip(props: { gateway: OutreachEnrollGateway | null; name: string }) {\n const chip = outreachGatewayChip(props.gateway)\n if (!chip) return null\n return (\n <Chip\n size=\"small\"\n variant={chip.tone === 'neutral' ? 'outlined' : 'filled'}\n color={GATEWAY_TONE_COLORS[chip.tone]}\n label={chip.label}\n aria-label={`Mail gateway for ${props.name}: ${chip.label}`}\n />\n )\n}\n\nfunction PersonRow(props: {\n person: OutreachEnrollPreviewPerson\n steps: readonly OutreachSequenceStep[]\n /** The step the enrollment begins at (AGL-3228); drafts before it are not shown. */\n startStepIndex: number\n supplied: Supplied | undefined\n onSupply(next: Partial<Supplied>): void\n emailPreview:\n | { status: 'loading' }\n | { status: 'ready'; answer: OutreachPreviewResponse }\n | { status: 'failed'; message: string }\n | undefined\n onPreviewEmail(): void\n stepTest: StepTest | undefined\n onSendTest(): void\n onCurate(): void\n onWriteThemselves(): void\n disabled: boolean\n}) {\n const { person, supplied, disabled } = props\n const name = person.name || person.email || person.personId\n const line = supplied?.personalLine ?? ''\n const tooLong = line.trim().length > OUTREACH_PERSONAL_LINE_MAX\n const curation = supplied?.curation ?? { status: 'idle' }\n const drafts = liveDrafts(supplied, props.startStepIndex).sort((a, b) => a.stepIndex - b.stepIndex)\n const usedCount = drafts.filter((draft) => draft.decision === 'use').length\n return (\n <Paper component=\"li\" variant=\"outlined\" sx={{ p: 1.5 }} aria-label={name}>\n <Stack spacing={1}>\n <Stack\n direction={{ xs: 'column', sm: 'row' }}\n spacing={1}\n sx={{ alignItems: { sm: 'center' } }}\n >\n <Stack sx={{ flexGrow: 1, minWidth: 0 }}>\n <Typography variant=\"body2\">{name}</Typography>\n {person.email && person.email !== name ? (\n <Typography variant=\"caption\" color=\"text.secondary\">\n {person.email}\n </Typography>\n ) : null}\n </Stack>\n <Stack direction=\"row\" spacing={1} sx={{ alignItems: 'center' }}>\n {person.target === 'lead' ? (\n <Chip size=\"small\" variant=\"outlined\" label=\"Lead\" />\n ) : null}\n {person.cold ? (\n <Chip size=\"small\" variant=\"outlined\" label=\"Cold\" />\n ) : null}\n <GatewayChip gateway={person.gateway} name={name} />\n <Chip\n size=\"small\"\n label={STATUS_LABELS[person.status]}\n color={STATUS_COLORS[person.status]}\n />\n </Stack>\n </Stack>\n {person.status === 'blocked' ? (\n <Stack component=\"ul\" spacing={0.5} sx={{ m: 0, pl: 2.5 }}>\n {person.blocks.map((block) => (\n <Typography\n key={block.code}\n component=\"li\"\n variant=\"body2\"\n color=\"text.secondary\"\n >\n {block.reason}\n </Typography>\n ))}\n </Stack>\n ) : (\n <Stack spacing={1}>\n <FormControlLabel\n control={\n <Checkbox\n checked={supplied?.include ?? true}\n onChange={(event) =>\n props.onSupply({ include: event.target.checked })\n }\n disabled={disabled}\n />\n }\n label=\"Enroll this person\"\n />\n {supplied?.include === false && outreachGatewayRefusedThisWeek(person.gateway) ? (\n <Typography variant=\"caption\" color=\"text.secondary\">\n {`Left un-ticked: their mail gateway refused ${person.gateway?.blocked7 === 1 ? 'an email' : `${person.gateway?.blocked7} emails`} from this organization this week. Tick them to enroll anyway${person.gateway?.hold ? ' — the email will go, and it is your call' : ''}.`}\n </Typography>\n ) : null}\n {supplied?.include === false ? null : (\n <>\n <TextField\n label={\n person.requires.personalLine\n ? 'Personal line'\n : 'Personal line (optional)'\n }\n placeholder=\"One sentence on why you're writing to this person now.\"\n value={line}\n onChange={(event) =>\n props.onSupply({ personalLine: event.target.value })\n }\n disabled={disabled}\n required={person.requires.personalLine}\n error={tooLong}\n helperText={\n tooLong\n ? `Keep it to one sentence, under ${OUTREACH_PERSONAL_LINE_MAX} characters.`\n : 'Goes where the emails say {{enrollment.personalLine}}.'\n }\n fullWidth\n size=\"small\"\n />\n {person.requires.attestations.length ? (\n <FormGroup aria-label={`What you confirm about ${name}`}>\n {person.requires.attestations.map((kind) => (\n <FormControlLabel\n key={kind}\n control={\n <Checkbox\n checked={\n supplied?.attestations.includes(kind) ?? false\n }\n onChange={(event) =>\n props.onSupply({\n attestations: event.target.checked\n ? [...(supplied?.attestations ?? []), kind]\n : (supplied?.attestations ?? []).filter(\n (entry) => entry !== kind,\n ),\n })\n }\n disabled={disabled}\n />\n }\n label={OUTREACH_ATTESTATION_LABELS[kind]}\n />\n ))}\n </FormGroup>\n ) : null}\n <Stack useFlexGap direction=\"row\" spacing={1} sx={{ flexWrap: 'wrap', rowGap: 1 }}>\n <Button\n size=\"small\"\n onClick={props.onPreviewEmail}\n disabled={disabled}\n >\n Preview the first email\n </Button>\n <Button\n size=\"small\"\n onClick={props.onSendTest}\n disabled={disabled || props.stepTest?.status === 'sending'}\n >\n {props.stepTest?.status === 'sending' ? 'Sending…' : 'Send me this as a test'}\n </Button>\n <Button\n size=\"small\"\n onClick={props.onCurate}\n disabled={disabled || curation.status === 'drafting'}\n >\n {drafts.length ? 'Curate again' : 'Curate for this person'}\n </Button>\n </Stack>\n {props.stepTest?.status === 'failed' ? (\n <Alert severity=\"error\">{props.stepTest.message}</Alert>\n ) : null}\n {props.stepTest?.status === 'sent' ? (\n <Alert severity=\"success\">\n {`Sent to ${props.stepTest.answer.sentTo} as “${props.stepTest.answer.subject}”. ${name} was not enrolled.`}\n </Alert>\n ) : null}\n {curation.status === 'drafting' ? (\n <OutreachLoading label=\"Drafting their emails…\" />\n ) : null}\n {curation.status === 'failed' ? (\n <Stack spacing={1}>\n <Alert severity=\"warning\">{curation.message}</Alert>\n <Stack direction=\"row\">\n <Button size=\"small\" onClick={props.onWriteThemselves} disabled={disabled}>\n Write them yourself\n </Button>\n </Stack>\n </Stack>\n ) : null}\n {drafts.length ? (\n <Stack spacing={1} aria-label={`Curated emails for ${name}`}>\n <Typography variant=\"caption\" color=\"text.secondary\">\n {usedCount\n ? `${usedCount} of ${drafts.length} ${drafts.length === 1 ? 'email' : 'emails'} curated for ${name}. Nothing is sent that you haven't confirmed.`\n : `Their emails, rewritten for them. Read each one, edit it, and use it or keep the template.`}\n </Typography>\n {drafts.map((draft) => (\n <OutreachCuratedStepEditor\n key={draft.stepIndex}\n draft={draft}\n label={outreachEmailStepLabel(props.steps, draft.stepIndex)}\n onChange={(next) =>\n props.onSupply({ drafts: { ...(supplied?.drafts ?? {}), [next.stepIndex]: next } })\n }\n disabled={disabled}\n />\n ))}\n </Stack>\n ) : null}\n {props.emailPreview?.status === 'loading' ? (\n <OutreachLoading label=\"Writing the email…\" />\n ) : null}\n {props.emailPreview?.status === 'failed' ? (\n <Alert severity=\"error\">{props.emailPreview.message}</Alert>\n ) : null}\n {props.emailPreview?.status === 'ready' ? (\n props.emailPreview.answer.error ? (\n <Alert severity=\"info\">\n {props.emailPreview.answer.error.message}\n </Alert>\n ) : (\n <Paper\n variant=\"outlined\"\n sx={{ p: 1.5 }}\n aria-label={`First email to ${name}`}\n >\n <Typography variant=\"body2\">{`Subject: ${props.emailPreview.answer.subject}`}</Typography>\n <Typography\n variant=\"body2\"\n sx={{\n whiteSpace: 'pre-wrap',\n wordBreak: 'break-word',\n mt: 1,\n }}\n >\n {props.emailPreview.answer.text}\n </Typography>\n </Paper>\n )\n ) : null}\n </>\n )}\n </Stack>\n )}\n </Stack>\n </Paper>\n )\n}\n\nfunction DoneSummary(props: {\n results: OutreachEnrollOutcome[]\n enrolled: number\n}) {\n const refused = props.results.filter(\n (\n result,\n ): result is Extract<OutreachEnrollOutcome, { outcome: 'blocked' }> =>\n result.outcome === 'blocked',\n )\n return (\n <Stack spacing={1.5}>\n <Alert severity={props.enrolled ? 'success' : 'info'}>\n {props.enrolled\n ? `Enrolled ${props.enrolled} ${props.enrolled === 1 ? 'person' : 'people'}. Their first step goes out in the mailbox's sending hours.`\n : 'Nobody was enrolled.'}\n </Alert>\n {refused.length ? (\n <Stack spacing={1}>\n <Typography variant=\"subtitle2\">\n Not enrolled, checked again just now:\n </Typography>\n {refused.map((result) => (\n <Stack key={result.personId} spacing={0.25}>\n <Typography variant=\"body2\">\n {result.email ?? result.personId}\n </Typography>\n {result.blocks.map((block) => (\n <Typography\n key={block.code}\n variant=\"body2\"\n color=\"text.secondary\"\n >\n {block.reason}\n </Typography>\n ))}\n </Stack>\n ))}\n </Stack>\n ) : null}\n </Stack>\n )\n}\n\nexport default OutreachEnrollDialog\n"],"names":["pluginDocsHelp","HelpTip","Alert","Button","Checkbox","Chip","Dialog","DialogActions","DialogContent","DialogTitle","FormControlLabel","FormGroup","List","ListItem","ListItemButton","ListItemIcon","ListItemText","MenuItem","Paper","Stack","Tab","Tabs","TextField","Typography","useMediaQuery","useTheme","useMemo","useState","isOutreachGatewayFronted","outreachGatewayChip","OUTREACH_ENROLL_BATCH_MAX","OUTREACH_ATTESTATION_LABELS","OUTREACH_PERSONAL_LINE_MAX","outreachStepName","outreachEmailStepLabel","OutreachCuratedStepEditor","outreachDraftState","outreachDraftToOverride","outreachMemberDraftStates","OutreachLoading","OutreachLoadProblem","useOutreachContactSearch","useOutreachLeadSearch","useOutreachSavedViews","STATUS_LABELS","eligible","needs_confirmation","blocked","STATUS_COLORS","GATEWAY_TONE_COLORS","refused","delivered","neutral","outreachGatewayRefusedThisWeek","gateway","blocked7","liveDrafts","supplied","startStepIndex","Object","values","drafts","filter","draft","stepIndex","usedOverrides","map","override","hasOpenDrafts","some","decision","outreachStartStepOptions","steps","_step","index","value","label","outreachStartStepHelp","skipped","outreachPersonReady","person","status","include","line","personalLine","trim","length","requires","attestations","every","kind","includes","OutreachEnrollDialog","props","orgId","sequence","api","theme","narrow","breakpoints","down","tab","setTab","viewId","setViewId","text","setText","picked","setPicked","Map","leadText","setLeadText","pickedLeads","setPickedLeads","stage","setStage","problem","setProblem","setSupplied","emailPreview","setEmailPreview","stepTests","setStepTests","setStartStepIndex","startOptions","views","open","uid","search","hostId","contactGroupId","leadSearch","enabled","reset","close","onClose","preview","source","answer","previewEnrollment","id","fromEntries","people","personId","error","message","ready","waiting","enroll","result","target","leadId","contactId","stepOverrides","results","enrolled","supply","next","previous","previewEmail","overrides","sequenceId","curate","curation","curateDrafts","audit","prompt","model","writeThemselves","stepIndexes","step","sendTest","sendStepTest","title","name","fullWidth","maxWidth","fullScreen","aria-label","direction","spacing","sx","alignItems","span","anchor","dividers","severity","onChange","_event","variant","scrollButtons","allowScrollButtonsMobile","what","data","select","event","helperText","view","section","placeholder","autoFocus","idle","color","dense","lead","checked","has","disablePadding","onClick","delete","size","set","edge","tabIndex","disableRipple","primary","email","secondary","useFlexGap","flexWrap","rowGap","onDelete","contact","summary","truncated","total","Number","disabled","option","component","listStyle","p","m","PersonRow","onSupply","onPreviewEmail","stepTest","onSendTest","onCurate","onWriteThemselves","DoneSummary","leadIds","keys","contactIds","displayName","count","fronted","GatewayChip","chip","tone","tooLong","sort","a","b","usedCount","xs","sm","flexGrow","minWidth","cold","pl","blocks","block","reason","code","control","hold","required","entry","sentTo","subject","whiteSpace","wordBreak","mt","outcome"],"mappings":"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"}
|
|
@@ -676,6 +676,7 @@ export function OutreachEnrollmentDetail(props) {
|
|
|
676
676
|
contentGutterY: true,
|
|
677
677
|
HeaderProps: {
|
|
678
678
|
action: /*#__PURE__*/ _jsxs(Stack, {
|
|
679
|
+
useFlexGap: true,
|
|
679
680
|
direction: "row",
|
|
680
681
|
spacing: 1,
|
|
681
682
|
sx: {
|
|
@@ -703,6 +704,7 @@ export function OutreachEnrollmentDetail(props) {
|
|
|
703
704
|
spacing: 2,
|
|
704
705
|
children: [
|
|
705
706
|
/*#__PURE__*/ _jsxs(Stack, {
|
|
707
|
+
useFlexGap: true,
|
|
706
708
|
direction: "row",
|
|
707
709
|
spacing: 1,
|
|
708
710
|
sx: {
|
|
@@ -765,6 +767,7 @@ export function OutreachEnrollmentDetail(props) {
|
|
|
765
767
|
children: enrollment.stopDetail || 'Their mail gateway refused this sender, so the next email is held. Resume to send it anyway.'
|
|
766
768
|
}) : null,
|
|
767
769
|
figures.anything ? /*#__PURE__*/ _jsxs(Stack, {
|
|
770
|
+
useFlexGap: true,
|
|
768
771
|
direction: "row",
|
|
769
772
|
spacing: 3,
|
|
770
773
|
sx: {
|