@elevasis/ui 2.28.0 → 2.29.0
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/dist/api/index.js +2 -2
- package/dist/app/index.d.ts +6 -12
- package/dist/app/index.js +4 -4
- package/dist/charts/index.js +3 -3
- package/dist/{chunk-OHXU5WWK.js → chunk-3DUOPXOJ.js} +146 -9
- package/dist/{chunk-LWKZ3BCC.js → chunk-5CW2HXQA.js} +4 -4
- package/dist/{chunk-JKBGDFX2.js → chunk-65RQE3XF.js} +378 -254
- package/dist/{chunk-XZSEPJZQ.js → chunk-6NHCE7JM.js} +49 -28
- package/dist/{chunk-RIFTUOPE.js → chunk-6WXDE5LZ.js} +1 -1
- package/dist/{chunk-SGS4CQ2B.js → chunk-7E3FUTND.js} +1 -1
- package/dist/{chunk-UPMX5GJI.js → chunk-A7R2URMV.js} +88 -26
- package/dist/{chunk-UY5I2KOZ.js → chunk-AK5E6ILJ.js} +9 -8
- package/dist/{chunk-G26INIF3.js → chunk-CEHUFNAL.js} +1 -1
- package/dist/{chunk-ONFKASZI.js → chunk-CLUP5H3C.js} +7 -10
- package/dist/{chunk-MYEOTM7D.js → chunk-CN2HC4D4.js} +5 -1
- package/dist/chunk-FFDAE2QI.js +330 -0
- package/dist/{chunk-WUVR4QY6.js → chunk-FGDUK74A.js} +4 -4
- package/dist/{chunk-YHBPR67D.js → chunk-HNFQCOD2.js} +4 -4
- package/dist/{chunk-QD4X4H5A.js → chunk-HXZQWMKE.js} +2 -3
- package/dist/{chunk-KEFWANZY.js → chunk-JCGD4GM6.js} +5 -1
- package/dist/{chunk-YO2YORW4.js → chunk-OHGNCWJP.js} +3 -3
- package/dist/{chunk-JPGX3533.js → chunk-OIMPGKDB.js} +2 -2
- package/dist/{chunk-W2ZTLH7Y.js → chunk-OWESKPTJ.js} +85 -26
- package/dist/{chunk-G66QFZXD.js → chunk-QNL7UI5G.js} +15 -9
- package/dist/{chunk-OGXKOMUT.js → chunk-SZWXQHKO.js} +2 -2
- package/dist/{chunk-ZFLM2YVW.js → chunk-Y3YJKKEB.js} +1 -1
- package/dist/components/index.d.ts +16 -14
- package/dist/components/index.js +26 -26
- package/dist/features/auth/index.d.ts +6 -12
- package/dist/features/auth/index.js +1 -0
- package/dist/features/crm/index.d.ts +16 -14
- package/dist/features/crm/index.js +9 -9
- package/dist/features/dashboard/index.d.ts +16 -3
- package/dist/features/dashboard/index.js +10 -10
- package/dist/features/delivery/index.d.ts +6 -12
- package/dist/features/delivery/index.js +9 -9
- package/dist/features/knowledge/index.js +42 -20
- package/dist/features/lead-gen/index.d.ts +187 -24
- package/dist/features/lead-gen/index.js +10 -10
- package/dist/features/monitoring/index.js +11 -11
- package/dist/features/monitoring/requests/index.js +8 -8
- package/dist/features/operations/index.d.ts +16 -3
- package/dist/features/operations/index.js +15 -15
- package/dist/features/settings/index.d.ts +6 -12
- package/dist/features/settings/index.js +9 -9
- package/dist/hooks/delivery/index.d.ts +6 -12
- package/dist/hooks/delivery/index.js +2 -2
- package/dist/hooks/index.d.ts +110 -28
- package/dist/hooks/index.js +8 -8
- package/dist/hooks/published.d.ts +110 -28
- package/dist/hooks/published.js +8 -8
- package/dist/index.d.ts +149 -31
- package/dist/index.js +8 -8
- package/dist/initialization/index.d.ts +6 -12
- package/dist/knowledge/index.d.ts +44 -1
- package/dist/knowledge/index.js +149 -12
- package/dist/profile/index.d.ts +6 -12
- package/dist/provider/index.d.ts +44 -12
- package/dist/provider/index.js +6 -6
- package/dist/provider/published.d.ts +44 -12
- package/dist/provider/published.js +5 -5
- package/dist/supabase/index.d.ts +12 -24
- package/dist/test-utils/index.js +2 -2
- package/dist/typeform/index.d.ts +5 -1
- package/dist/typeform/index.js +52 -7
- package/dist/types/index.d.ts +7 -13
- package/dist/utils/index.d.ts +1 -3
- package/dist/utils/index.js +1 -1
- package/dist/vite/index.js +2 -2
- package/dist/vite-plugin-knowledge/index.js +1 -1
- package/package.json +5 -5
- package/dist/chunk-4KTLOK7K.js +0 -230
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { DEFAULT_ORGANIZATION_MODEL_PROSPECTING } from './chunk-
|
|
1
|
+
import { DEFAULT_ORGANIZATION_MODEL_PROSPECTING, PROSPECTING_STEPS } from './chunk-FFDAE2QI.js';
|
|
2
2
|
import { sanitizeInput } from './chunk-3MEXPLWT.js';
|
|
3
3
|
import { PageContainer } from './chunk-BZZCNLT6.js';
|
|
4
4
|
import { TableSelectionToolbar, SortableHeader } from './chunk-TUMSNGTX.js';
|
|
@@ -6,15 +6,15 @@ import { SubshellNavItem } from './chunk-X4WBGKJQ.js';
|
|
|
6
6
|
import { SubshellSidebarSection } from './chunk-IIMU5YAJ.js';
|
|
7
7
|
import { FilterBar } from './chunk-PDHTXPSF.js';
|
|
8
8
|
import { CustomModal } from './chunk-KVJ3LFH2.js';
|
|
9
|
-
import { acquisitionListKeys, useListsTelemetry, useLists, useCreateList, useTableSort, sortData, usePaginationState, useTableSelection, useWorkflowExecution, useList, useListProgress, useListExecutions, useDeleteList, useCompanyFacets, useCompanies, useDeleteCompanies, useContacts, useDeleteContacts, useListMembers, useListMember, useTransitionListMember, useDeriveActions, useArtifacts } from './chunk-
|
|
10
|
-
import { showApiErrorNotification, showSuccessNotification } from './chunk-
|
|
11
|
-
import { PageTitleCaption, CenteredErrorState, StatCard, CardHeader, EmptyState, JsonViewer } from './chunk-
|
|
12
|
-
import { useListActions, LEAD_GEN_STAGE_CATALOG, LEAD_GEN_PIPELINE_DEFINITIONS, findPipeline } from './chunk-
|
|
9
|
+
import { acquisitionListKeys, useListsTelemetry, useLists, useCreateList, useTableSort, sortData, usePaginationState, useTableSelection, useWorkflowExecution, useList, useListProgress, useListExecutions, useDeleteList, useCompanyFacets, useCompanies, useDeleteCompanies, useContacts, useDeleteContacts, useListMembers, useListMember, useTransitionListMember, useDeriveActions, useArtifacts } from './chunk-HNFQCOD2.js';
|
|
10
|
+
import { showApiErrorNotification, showSuccessNotification } from './chunk-CEHUFNAL.js';
|
|
11
|
+
import { PageTitleCaption, CenteredErrorState, StatCard, CardHeader, EmptyState, JsonViewer } from './chunk-6WXDE5LZ.js';
|
|
12
|
+
import { useListActions, LEAD_GEN_STAGE_CATALOG, LEAD_GEN_PIPELINE_DEFINITIONS, findPipeline } from './chunk-OWESKPTJ.js';
|
|
13
13
|
import { SubshellContentContainer } from './chunk-TKAYX2SP.js';
|
|
14
14
|
import { useRouterContext } from './chunk-Q7DJKLEN.js';
|
|
15
15
|
import { useElevasisServices } from './chunk-5WWZXCS5.js';
|
|
16
16
|
import { Stack, Group, Title, Text, Alert, Button, Collapse, Paper, Anchor, ActionIcon, Divider, Box, SimpleGrid, Badge, Card, Center, Loader, Table, TextInput, Select, Checkbox, Pagination, Textarea, Tooltip, Tabs, ThemeIcon, Pill, SegmentedControl, UnstyledButton, Drawer, JsonInput, Switch, NumberInput, MultiSelect, TagsInput, ScrollArea } from '@mantine/core';
|
|
17
|
-
import { IconLayoutGrid, IconList, IconBuilding, IconAddressBook, IconTarget, IconExternalLink, IconX, IconAlertCircle, IconPlayerPlay, IconArrowRight, IconSparkles, IconListDetails, IconPlus, IconSearch, IconAlertTriangle, IconLayoutDashboard, IconBolt, IconCopy, IconUsers, IconTrash, IconBuildingFactory2, IconArrowLeft, IconChevronDown, IconChevronRight, IconRefresh, IconMail, IconUser, IconDatabase } from '@tabler/icons-react';
|
|
17
|
+
import { IconLayoutGrid, IconList, IconBuilding, IconAddressBook, IconTarget, IconExternalLink, IconX, IconAlertCircle, IconPlayerPlay, IconArrowRight, IconSparkles, IconListDetails, IconPlus, IconSearch, IconAlertTriangle, IconLayoutDashboard, IconBolt, IconCopy, IconUsers, IconTrash, IconBuildingFactory2, IconArrowLeft, IconChevronDown, IconChevronRight, IconRefresh, IconSettings, IconMail, IconUser, IconDatabase } from '@tabler/icons-react';
|
|
18
18
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
19
19
|
import { Link, useNavigate, useSearch } from '@tanstack/react-router';
|
|
20
20
|
import { useState, useRef, useMemo, useEffect, Fragment as Fragment$1 } from 'react';
|
|
@@ -1208,17 +1208,9 @@ function LeadGenListsPage() {
|
|
|
1208
1208
|
)
|
|
1209
1209
|
] }) });
|
|
1210
1210
|
}
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
month: "short",
|
|
1215
|
-
day: "numeric",
|
|
1216
|
-
year: "numeric",
|
|
1217
|
-
hour: "numeric",
|
|
1218
|
-
minute: "2-digit"
|
|
1219
|
-
});
|
|
1220
|
-
}
|
|
1221
|
-
function resolveMemberStateLabel(member) {
|
|
1211
|
+
|
|
1212
|
+
// src/lib/lead-gen/legacy-pipeline.ts
|
|
1213
|
+
function resolveLegacyListMemberPipelineLabel(member) {
|
|
1222
1214
|
const defs = LEAD_GEN_PIPELINE_DEFINITIONS["acq.list-member"];
|
|
1223
1215
|
if (!defs) return null;
|
|
1224
1216
|
const pipeline = findPipeline(defs, member.pipelineKey);
|
|
@@ -1231,23 +1223,21 @@ function resolveMemberStateLabel(member) {
|
|
|
1231
1223
|
stateLabel: state?.label ?? member.stateKey
|
|
1232
1224
|
};
|
|
1233
1225
|
}
|
|
1226
|
+
function formatDateTime(value) {
|
|
1227
|
+
if (!value) return "Not yet";
|
|
1228
|
+
return new Date(value).toLocaleString("en-US", {
|
|
1229
|
+
month: "short",
|
|
1230
|
+
day: "numeric",
|
|
1231
|
+
year: "numeric",
|
|
1232
|
+
hour: "numeric",
|
|
1233
|
+
minute: "2-digit"
|
|
1234
|
+
});
|
|
1235
|
+
}
|
|
1234
1236
|
function getMemberStateColor(stateKey) {
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
case "interested":
|
|
1240
|
-
return "green";
|
|
1241
|
-
case "uploaded":
|
|
1242
|
-
case "discovered":
|
|
1243
|
-
case "extracted":
|
|
1244
|
-
case "populated":
|
|
1245
|
-
return "blue";
|
|
1246
|
-
case "pending":
|
|
1247
|
-
return "gray";
|
|
1248
|
-
default:
|
|
1249
|
-
return "gray";
|
|
1250
|
-
}
|
|
1237
|
+
const stage = LEAD_GEN_STAGE_CATALOG[stateKey];
|
|
1238
|
+
if (stage?.entity === "contact") return "green";
|
|
1239
|
+
if (stage?.entity === "company") return "blue";
|
|
1240
|
+
return "gray";
|
|
1251
1241
|
}
|
|
1252
1242
|
function ArtifactsPanel({ listMemberId }) {
|
|
1253
1243
|
const { data, isLoading, error } = useArtifacts({ ownerKind: "list_member", ownerId: listMemberId });
|
|
@@ -1288,7 +1278,7 @@ function ListMemberDrawerContent({ member, listId }) {
|
|
|
1288
1278
|
[member]
|
|
1289
1279
|
);
|
|
1290
1280
|
const derivedActions = useDeriveActions(statefulItem);
|
|
1291
|
-
const resolved =
|
|
1281
|
+
const resolved = resolveLegacyListMemberPipelineLabel(member);
|
|
1292
1282
|
const contactName = [member.contact?.firstName, member.contact?.lastName].filter(Boolean).join(" ").trim() || member.contact?.email || "\u2014";
|
|
1293
1283
|
return /* @__PURE__ */ jsxs(Stack, { gap: "md", p: "md", children: [
|
|
1294
1284
|
/* @__PURE__ */ jsxs(Stack, { gap: 4, children: [
|
|
@@ -1535,6 +1525,12 @@ var STAGE_COLOR_SETS = {
|
|
|
1535
1525
|
border: "color-mix(in srgb, var(--color-border) 68%, var(--color-success))",
|
|
1536
1526
|
text: "var(--color-text)"
|
|
1537
1527
|
},
|
|
1528
|
+
"decision-makers-enriched": {
|
|
1529
|
+
accent: "color-mix(in srgb, var(--color-primary) 66%, var(--color-warning))",
|
|
1530
|
+
background: "color-mix(in srgb, var(--color-primary) 12%, transparent)",
|
|
1531
|
+
border: "color-mix(in srgb, var(--color-border) 66%, var(--color-primary))",
|
|
1532
|
+
text: "var(--color-text)"
|
|
1533
|
+
},
|
|
1538
1534
|
discovered: {
|
|
1539
1535
|
accent: "color-mix(in srgb, var(--color-primary) 70%, var(--color-warning))",
|
|
1540
1536
|
background: "color-mix(in srgb, var(--color-warning) 10%, transparent)",
|
|
@@ -2298,197 +2294,120 @@ function ListBuilderPage({ listId }) {
|
|
|
2298
2294
|
)
|
|
2299
2295
|
] });
|
|
2300
2296
|
}
|
|
2301
|
-
|
|
2302
|
-
|
|
2303
|
-
|
|
2304
|
-
|
|
2305
|
-
|
|
2306
|
-
|
|
2307
|
-
|
|
2308
|
-
|
|
2297
|
+
|
|
2298
|
+
// src/lib/lead-gen/processing-state.ts
|
|
2299
|
+
function isRecord(value) {
|
|
2300
|
+
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
2301
|
+
}
|
|
2302
|
+
function parseProcessingStageStatus(value) {
|
|
2303
|
+
if (value === true || value === "success") return "success";
|
|
2304
|
+
if (value === "no_result" || value === "noResult") return "noResult";
|
|
2305
|
+
if (value === "skipped") return "skipped";
|
|
2306
|
+
if (value === "error") return "error";
|
|
2307
|
+
if (isRecord(value)) return parseProcessingStageStatus(value.status);
|
|
2308
|
+
if (typeof value === "string") return "other";
|
|
2309
|
+
return null;
|
|
2310
|
+
}
|
|
2311
|
+
function parseProcessingState(value) {
|
|
2312
|
+
const parsed = {};
|
|
2313
|
+
const stageStatuses = {};
|
|
2314
|
+
const knownStageStatuses = {};
|
|
2315
|
+
const unknownFields = {};
|
|
2316
|
+
if (!isRecord(value)) {
|
|
2317
|
+
Object.defineProperties(parsed, {
|
|
2318
|
+
stageStatuses: { value: stageStatuses },
|
|
2319
|
+
knownStageStatuses: { value: knownStageStatuses },
|
|
2320
|
+
unknownFields: { value: unknownFields }
|
|
2321
|
+
});
|
|
2322
|
+
return parsed;
|
|
2323
|
+
}
|
|
2324
|
+
for (const [key, rawStatus] of Object.entries(value)) {
|
|
2325
|
+
const parsedStatus = parseProcessingStageStatus(rawStatus);
|
|
2326
|
+
const isKnownStage = Boolean(LEAD_GEN_STAGE_CATALOG[key]);
|
|
2327
|
+
if (!parsedStatus) {
|
|
2328
|
+
unknownFields[key] = rawStatus;
|
|
2329
|
+
continue;
|
|
2330
|
+
}
|
|
2331
|
+
stageStatuses[key] = parsedStatus;
|
|
2332
|
+
parsed[key] = parsedStatus;
|
|
2333
|
+
if (isKnownStage) {
|
|
2334
|
+
knownStageStatuses[key] = parsedStatus;
|
|
2335
|
+
} else {
|
|
2336
|
+
unknownFields[key] = rawStatus;
|
|
2337
|
+
}
|
|
2338
|
+
}
|
|
2339
|
+
Object.defineProperties(parsed, {
|
|
2340
|
+
stageStatuses: { value: stageStatuses },
|
|
2341
|
+
knownStageStatuses: { value: knownStageStatuses },
|
|
2342
|
+
unknownFields: { value: unknownFields }
|
|
2309
2343
|
});
|
|
2344
|
+
return parsed;
|
|
2310
2345
|
}
|
|
2311
|
-
function
|
|
2312
|
-
|
|
2313
|
-
return
|
|
2346
|
+
function readLeadGenProcessingState(row) {
|
|
2347
|
+
if (!isRecord(row)) return null;
|
|
2348
|
+
return row.processingState ?? row.processing_state ?? row.pipelineStatus ?? null;
|
|
2314
2349
|
}
|
|
2315
|
-
function
|
|
2316
|
-
|
|
2317
|
-
|
|
2318
|
-
|
|
2319
|
-
case "enriching":
|
|
2320
|
-
return "blue";
|
|
2321
|
-
case "launched":
|
|
2322
|
-
return "green";
|
|
2323
|
-
case "closing":
|
|
2324
|
-
return "yellow";
|
|
2325
|
-
case "archived":
|
|
2326
|
-
return "red";
|
|
2327
|
-
default:
|
|
2328
|
-
return "gray";
|
|
2329
|
-
}
|
|
2350
|
+
function readLeadGenStateKey(row) {
|
|
2351
|
+
if (!isRecord(row)) return null;
|
|
2352
|
+
const stateKey = row.stateKey ?? row.state_key;
|
|
2353
|
+
return typeof stateKey === "string" && stateKey.length > 0 ? stateKey : null;
|
|
2330
2354
|
}
|
|
2331
|
-
function
|
|
2332
|
-
|
|
2333
|
-
|
|
2334
|
-
|
|
2335
|
-
|
|
2336
|
-
|
|
2337
|
-
|
|
2338
|
-
|
|
2339
|
-
case "discovered":
|
|
2340
|
-
case "extracted":
|
|
2341
|
-
case "populated":
|
|
2342
|
-
return "blue";
|
|
2343
|
-
case "pending":
|
|
2344
|
-
return "gray";
|
|
2345
|
-
default:
|
|
2346
|
-
return "gray";
|
|
2355
|
+
function getDisplayLeadGenStageStateFor(row, entity) {
|
|
2356
|
+
const parsed = parseProcessingState(readLeadGenProcessingState(row));
|
|
2357
|
+
const latest = Object.values(LEAD_GEN_STAGE_CATALOG).filter((stage) => stage.entity === entity && parsed.knownStageStatuses[stage.key]).sort((a, b) => b.order - a.order)[0];
|
|
2358
|
+
if (latest) {
|
|
2359
|
+
return {
|
|
2360
|
+
stageKey: latest.key,
|
|
2361
|
+
stageStatus: parsed.knownStageStatuses[latest.key]
|
|
2362
|
+
};
|
|
2347
2363
|
}
|
|
2364
|
+
const unknownStageKey = Object.keys(parsed.stageStatuses).find((stageKey) => !LEAD_GEN_STAGE_CATALOG[stageKey]);
|
|
2365
|
+
if (unknownStageKey) {
|
|
2366
|
+
return {
|
|
2367
|
+
stageKey: unknownStageKey,
|
|
2368
|
+
stageStatus: parsed.stageStatuses[unknownStageKey]
|
|
2369
|
+
};
|
|
2370
|
+
}
|
|
2371
|
+
const stateKey = readLeadGenStateKey(row);
|
|
2372
|
+
return stateKey && LEAD_GEN_STAGE_CATALOG[stateKey] ? { stageKey: stateKey, stageStatus: null } : { stageKey: null, stageStatus: null };
|
|
2348
2373
|
}
|
|
2374
|
+
|
|
2375
|
+
// src/features/lead-gen/build-state.ts
|
|
2376
|
+
var ORPHAN_STAGE_ORDER = 9999;
|
|
2349
2377
|
function asRecord2(value) {
|
|
2350
2378
|
return value && typeof value === "object" && !Array.isArray(value) ? value : {};
|
|
2351
2379
|
}
|
|
2352
|
-
function
|
|
2353
|
-
|
|
2354
|
-
case "completed":
|
|
2355
|
-
case "success":
|
|
2356
|
-
case "succeeded":
|
|
2357
|
-
return "green";
|
|
2358
|
-
case "running":
|
|
2359
|
-
case "pending":
|
|
2360
|
-
case "queued":
|
|
2361
|
-
return "blue";
|
|
2362
|
-
case "failed":
|
|
2363
|
-
case "error":
|
|
2364
|
-
case "cancelled":
|
|
2365
|
-
return "red";
|
|
2366
|
-
default:
|
|
2367
|
-
return "gray";
|
|
2368
|
-
}
|
|
2369
|
-
}
|
|
2370
|
-
function getRunInput(run) {
|
|
2371
|
-
const payload = asRecord2(run.payload);
|
|
2372
|
-
return run.input ?? run.inputs ?? payload.input ?? payload.inputs;
|
|
2373
|
-
}
|
|
2374
|
-
function sanitizeStepInput(value, _capabilityKey) {
|
|
2375
|
-
return value;
|
|
2376
|
-
}
|
|
2377
|
-
function getDefaultStepInput(list, action) {
|
|
2378
|
-
return asRecord2(action?.defaultInput?.(list));
|
|
2379
|
-
}
|
|
2380
|
-
function getInitialStepInput(list, action) {
|
|
2381
|
-
return getDefaultStepInput(list, action);
|
|
2382
|
-
}
|
|
2383
|
-
function mergeStepRunInput(list, action, inputAtSubmit) {
|
|
2380
|
+
function defineMvpBuildStep(step, emptyBlockedText) {
|
|
2381
|
+
const description = "description" in step && typeof step.description === "string" ? step.description : `Run ${step.label.toLowerCase()} for this list.`;
|
|
2384
2382
|
return {
|
|
2385
|
-
...
|
|
2386
|
-
|
|
2383
|
+
...step,
|
|
2384
|
+
description,
|
|
2385
|
+
emptyBlockedText
|
|
2387
2386
|
};
|
|
2388
2387
|
}
|
|
2389
|
-
var ORPHAN_STAGE_ORDER = 9999;
|
|
2390
|
-
var EMPTY_SELECTION2 = {
|
|
2391
|
-
selectedCompanyIds: [],
|
|
2392
|
-
selectedContactIds: []
|
|
2393
|
-
};
|
|
2394
2388
|
var MVP_BUILD_STEPS = [
|
|
2395
|
-
|
|
2396
|
-
|
|
2397
|
-
|
|
2398
|
-
|
|
2399
|
-
|
|
2400
|
-
|
|
2401
|
-
|
|
2402
|
-
|
|
2403
|
-
|
|
2404
|
-
|
|
2405
|
-
|
|
2406
|
-
|
|
2407
|
-
|
|
2408
|
-
|
|
2409
|
-
|
|
2410
|
-
|
|
2411
|
-
|
|
2412
|
-
|
|
2413
|
-
|
|
2414
|
-
|
|
2415
|
-
|
|
2416
|
-
|
|
2417
|
-
capabilityKey: "lead-gen.company.website-extract",
|
|
2418
|
-
defaultBatchSize: 50,
|
|
2419
|
-
maxBatchSize: 100,
|
|
2420
|
-
emptyBlockedText: "Source companies before website analysis can run."
|
|
2421
|
-
},
|
|
2422
|
-
{
|
|
2423
|
-
id: "qualify-companies",
|
|
2424
|
-
label: "Qualify companies",
|
|
2425
|
-
description: "Apply the ICP rubric to companies with enough context.",
|
|
2426
|
-
primaryEntity: "company",
|
|
2427
|
-
outputs: ["company"],
|
|
2428
|
-
stageKey: "qualified",
|
|
2429
|
-
dependsOn: ["analyze-websites"],
|
|
2430
|
-
dependencyMode: "per-record-eligibility",
|
|
2431
|
-
capabilityKey: "lead-gen.company.qualify",
|
|
2432
|
-
defaultBatchSize: 100,
|
|
2433
|
-
maxBatchSize: 250,
|
|
2434
|
-
emptyBlockedText: "Analyze websites before qualification can run."
|
|
2435
|
-
},
|
|
2436
|
-
{
|
|
2437
|
-
id: "find-contacts",
|
|
2438
|
-
label: "Find contacts",
|
|
2439
|
-
description: "Discover contacts for qualified companies.",
|
|
2440
|
-
primaryEntity: "contact",
|
|
2441
|
-
outputs: ["contact"],
|
|
2442
|
-
stageKey: "discovered",
|
|
2443
|
-
dependsOn: ["qualify-companies"],
|
|
2444
|
-
dependencyMode: "per-record-eligibility",
|
|
2445
|
-
capabilityKey: "lead-gen.contact.discover",
|
|
2446
|
-
defaultBatchSize: 50,
|
|
2447
|
-
maxBatchSize: 100,
|
|
2448
|
-
emptyBlockedText: "Qualify companies before contact discovery can run."
|
|
2449
|
-
},
|
|
2450
|
-
{
|
|
2451
|
-
id: "verify-emails",
|
|
2452
|
-
label: "Verify emails",
|
|
2453
|
-
description: "Verify deliverability for discovered contact emails.",
|
|
2454
|
-
primaryEntity: "contact",
|
|
2455
|
-
outputs: ["contact"],
|
|
2456
|
-
stageKey: "verified",
|
|
2457
|
-
dependsOn: ["find-contacts"],
|
|
2458
|
-
dependencyMode: "per-record-eligibility",
|
|
2459
|
-
capabilityKey: "lead-gen.contact.verify-email",
|
|
2460
|
-
defaultBatchSize: 100,
|
|
2461
|
-
maxBatchSize: 500,
|
|
2462
|
-
emptyBlockedText: "Find contacts before email verification can run."
|
|
2463
|
-
},
|
|
2464
|
-
{
|
|
2465
|
-
id: "personalize",
|
|
2466
|
-
label: "Personalize",
|
|
2467
|
-
description: "Generate outreach personalization for verified contacts.",
|
|
2468
|
-
primaryEntity: "contact",
|
|
2469
|
-
outputs: ["contact"],
|
|
2470
|
-
stageKey: "personalized",
|
|
2471
|
-
dependsOn: ["verify-emails"],
|
|
2472
|
-
dependencyMode: "per-record-eligibility",
|
|
2473
|
-
capabilityKey: "lead-gen.contact.personalize",
|
|
2474
|
-
defaultBatchSize: 25,
|
|
2475
|
-
maxBatchSize: 100,
|
|
2476
|
-
emptyBlockedText: "Verify emails before personalization can run."
|
|
2477
|
-
},
|
|
2478
|
-
{
|
|
2479
|
-
id: "review",
|
|
2480
|
-
label: "Review",
|
|
2481
|
-
description: "Review personalized records before outreach handoff.",
|
|
2482
|
-
primaryEntity: "contact",
|
|
2483
|
-
outputs: ["export"],
|
|
2484
|
-
stageKey: "uploaded",
|
|
2485
|
-
dependsOn: ["personalize"],
|
|
2486
|
-
dependencyMode: "per-record-eligibility",
|
|
2487
|
-
capabilityKey: "lead-gen.review.outreach-ready",
|
|
2488
|
-
defaultBatchSize: 25,
|
|
2489
|
-
maxBatchSize: 100,
|
|
2490
|
-
emptyBlockedText: "Personalize contacts before records are ready for review."
|
|
2491
|
-
}
|
|
2389
|
+
defineMvpBuildStep(
|
|
2390
|
+
PROSPECTING_STEPS.localServices.sourceCompanies,
|
|
2391
|
+
"No company source has been configured or populated yet."
|
|
2392
|
+
),
|
|
2393
|
+
defineMvpBuildStep(
|
|
2394
|
+
PROSPECTING_STEPS.localServices.analyzeWebsites,
|
|
2395
|
+
"Source companies before website analysis can run."
|
|
2396
|
+
),
|
|
2397
|
+
defineMvpBuildStep(
|
|
2398
|
+
PROSPECTING_STEPS.localServices.qualifyCompanies,
|
|
2399
|
+
"Analyze websites before qualification can run."
|
|
2400
|
+
),
|
|
2401
|
+
defineMvpBuildStep(
|
|
2402
|
+
PROSPECTING_STEPS.localServices.findContacts,
|
|
2403
|
+
"Qualify companies before contact discovery can run."
|
|
2404
|
+
),
|
|
2405
|
+
defineMvpBuildStep(PROSPECTING_STEPS.localServices.verifyEmails, "Find contacts before email verification can run."),
|
|
2406
|
+
defineMvpBuildStep(PROSPECTING_STEPS.localServices.personalize, "Verify emails before personalization can run."),
|
|
2407
|
+
defineMvpBuildStep(
|
|
2408
|
+
PROSPECTING_STEPS.localServices.review,
|
|
2409
|
+
"Personalize contacts before records are ready for review."
|
|
2410
|
+
)
|
|
2492
2411
|
];
|
|
2493
2412
|
function sortStageKeys(keys) {
|
|
2494
2413
|
return keys.slice().sort((a, b) => {
|
|
@@ -2567,6 +2486,70 @@ function getStepActionLabel(kind) {
|
|
|
2567
2486
|
return "No action";
|
|
2568
2487
|
}
|
|
2569
2488
|
}
|
|
2489
|
+
function createCompleteStageCounts(total) {
|
|
2490
|
+
return {
|
|
2491
|
+
total,
|
|
2492
|
+
attempted: total,
|
|
2493
|
+
success: total,
|
|
2494
|
+
noResult: 0,
|
|
2495
|
+
skipped: 0,
|
|
2496
|
+
error: 0,
|
|
2497
|
+
other: 0,
|
|
2498
|
+
notAttempted: 0
|
|
2499
|
+
};
|
|
2500
|
+
}
|
|
2501
|
+
function isStageComplete(entry) {
|
|
2502
|
+
if (!entry || entry.total <= 0) return false;
|
|
2503
|
+
return entry.error === 0 && entry.attempted >= entry.total && entry.success + entry.noResult + entry.skipped + entry.other >= entry.total;
|
|
2504
|
+
}
|
|
2505
|
+
function getExecutionInput(run) {
|
|
2506
|
+
return asRecord2(run.input);
|
|
2507
|
+
}
|
|
2508
|
+
function isCompletedRun(run) {
|
|
2509
|
+
return run.status === "completed" || run.status === "success" || run.status === "succeeded";
|
|
2510
|
+
}
|
|
2511
|
+
function getApprovedCompanyIds(run) {
|
|
2512
|
+
const input = getExecutionInput(run);
|
|
2513
|
+
const raw = input.approvedCompanyIds;
|
|
2514
|
+
return Array.isArray(raw) ? raw.filter((value) => typeof value === "string") : [];
|
|
2515
|
+
}
|
|
2516
|
+
function hasApprovedExportRun(executions) {
|
|
2517
|
+
return executions.some((run) => {
|
|
2518
|
+
if (!isCompletedRun(run) || run.resourceId !== "lgn-06-export-list-workflow") return false;
|
|
2519
|
+
const input = getExecutionInput(run);
|
|
2520
|
+
return input.approved === true || getApprovedCompanyIds(run).length > 0;
|
|
2521
|
+
});
|
|
2522
|
+
}
|
|
2523
|
+
function hasCompletedSourcingRun(step, action, executions) {
|
|
2524
|
+
return executions.some((run) => isCompletedRun(run) && run.resourceId === (action?.resourceId ?? step.capabilityKey));
|
|
2525
|
+
}
|
|
2526
|
+
function deriveBusinessProgress(list, progress, actions = [], executions = []) {
|
|
2527
|
+
const byCompanyStage = { ...progress.byCompanyStage };
|
|
2528
|
+
const byContactStage = { ...progress.byContactStage };
|
|
2529
|
+
const steps = resolveBuildPlanSteps(list);
|
|
2530
|
+
for (const step of steps) {
|
|
2531
|
+
const stageProgress = step.primaryEntity === "company" ? byCompanyStage[step.stageKey] : byContactStage[step.stageKey];
|
|
2532
|
+
if (stageProgress || (step.dependsOn?.length ?? 0) > 0 || !step.outputs.includes("company")) continue;
|
|
2533
|
+
if (progress.totalCompanies <= 0) continue;
|
|
2534
|
+
const action = findActionForStep(actions, step);
|
|
2535
|
+
if (hasCompletedSourcingRun(step, action, executions) || step.stageKey === "populated") {
|
|
2536
|
+
byCompanyStage[step.stageKey] = createCompleteStageCounts(progress.totalCompanies);
|
|
2537
|
+
}
|
|
2538
|
+
}
|
|
2539
|
+
if (!isStageComplete(byCompanyStage.uploaded) && hasApprovedExportRun(executions)) {
|
|
2540
|
+
const exportedCount = Math.max(
|
|
2541
|
+
...executions.filter((run) => isCompletedRun(run) && run.resourceId === "lgn-06-export-list-workflow").map((run) => getApprovedCompanyIds(run).length),
|
|
2542
|
+
0
|
|
2543
|
+
);
|
|
2544
|
+
const total = exportedCount > 0 ? exportedCount : progress.totalCompanies;
|
|
2545
|
+
if (total > 0) byCompanyStage.uploaded = createCompleteStageCounts(total);
|
|
2546
|
+
}
|
|
2547
|
+
return {
|
|
2548
|
+
...progress,
|
|
2549
|
+
byCompanyStage,
|
|
2550
|
+
byContactStage
|
|
2551
|
+
};
|
|
2552
|
+
}
|
|
2570
2553
|
function getStepRecommendedAction(step, action, kind) {
|
|
2571
2554
|
if (!action || kind === "none") return void 0;
|
|
2572
2555
|
return {
|
|
@@ -2584,12 +2567,13 @@ function deriveBuildStepStates(list, progress, actions) {
|
|
|
2584
2567
|
const entityTotal = getEntityTotal(progress, step.primaryEntity);
|
|
2585
2568
|
const prerequisites = getPrerequisiteSteps(step, byStepId);
|
|
2586
2569
|
const hasDependencies = (step.dependsOn?.length ?? 0) > 0;
|
|
2587
|
-
const
|
|
2570
|
+
const prerequisiteEligibleTotal = prerequisites.reduce((sum, prerequisite) => sum + prerequisite.complete, 0);
|
|
2571
|
+
const eligibleTotal = hasDependencies ? entityTotal > 0 ? Math.min(entityTotal, prerequisiteEligibleTotal) : prerequisiteEligibleTotal : entityTotal > 0 ? entityTotal : 0;
|
|
2588
2572
|
const total = Math.max(stageProgress?.total ?? 0, entityTotal, eligibleTotal);
|
|
2589
2573
|
const complete = stageProgress ? stageProgress.success + stageProgress.noResult + stageProgress.skipped + stageProgress.other : 0;
|
|
2590
2574
|
const failed = stageProgress?.error ?? 0;
|
|
2591
2575
|
const ready = Math.max(0, eligibleTotal - complete - failed);
|
|
2592
|
-
const blocked = hasDependencies ? Math.max(
|
|
2576
|
+
const blocked = hasDependencies ? Math.max(total - eligibleTotal - complete - failed, 0) : 0;
|
|
2593
2577
|
const status = failed > 0 ? "failed" : ready > 0 ? "ready" : blocked > 0 || total === 0 ? "blocked" : "complete";
|
|
2594
2578
|
const action = findActionForStep(actions, step);
|
|
2595
2579
|
const nextActionKind = getStepActionKind(step, ready, failed, action);
|
|
@@ -2620,6 +2604,99 @@ function resolveBuildState(list, progress, actions) {
|
|
|
2620
2604
|
recommendedAction: recommendedStep?.recommendedAction ?? null
|
|
2621
2605
|
};
|
|
2622
2606
|
}
|
|
2607
|
+
function formatDateTime4(value) {
|
|
2608
|
+
if (!value) return "Not yet";
|
|
2609
|
+
return new Date(value).toLocaleString("en-US", {
|
|
2610
|
+
month: "short",
|
|
2611
|
+
day: "numeric",
|
|
2612
|
+
year: "numeric",
|
|
2613
|
+
hour: "numeric",
|
|
2614
|
+
minute: "2-digit"
|
|
2615
|
+
});
|
|
2616
|
+
}
|
|
2617
|
+
function contactDisplayName(firstName, lastName) {
|
|
2618
|
+
const full = [firstName, lastName].filter(Boolean).join(" ").trim();
|
|
2619
|
+
return full || "\u2014";
|
|
2620
|
+
}
|
|
2621
|
+
function getStatusColor4(status) {
|
|
2622
|
+
switch (status) {
|
|
2623
|
+
case "draft":
|
|
2624
|
+
return "gray";
|
|
2625
|
+
case "enriching":
|
|
2626
|
+
return "blue";
|
|
2627
|
+
case "launched":
|
|
2628
|
+
return "green";
|
|
2629
|
+
case "closing":
|
|
2630
|
+
return "yellow";
|
|
2631
|
+
case "archived":
|
|
2632
|
+
return "red";
|
|
2633
|
+
default:
|
|
2634
|
+
return "gray";
|
|
2635
|
+
}
|
|
2636
|
+
}
|
|
2637
|
+
function getMemberStateColor2(stateKey) {
|
|
2638
|
+
const stage = LEAD_GEN_STAGE_CATALOG[stateKey];
|
|
2639
|
+
if (stage?.entity === "contact") return "green";
|
|
2640
|
+
if (stage?.entity === "company") return "blue";
|
|
2641
|
+
return "gray";
|
|
2642
|
+
}
|
|
2643
|
+
function displayMemberStageFor(row, kind) {
|
|
2644
|
+
const stage = getDisplayLeadGenStageStateFor(row, kind);
|
|
2645
|
+
if (!stage.stageKey) return null;
|
|
2646
|
+
const catalogStage = LEAD_GEN_STAGE_CATALOG[stage.stageKey];
|
|
2647
|
+
return {
|
|
2648
|
+
key: stage.stageKey,
|
|
2649
|
+
label: catalogStage?.label ?? stage.stageKey
|
|
2650
|
+
};
|
|
2651
|
+
}
|
|
2652
|
+
function asRecord3(value) {
|
|
2653
|
+
return value && typeof value === "object" && !Array.isArray(value) ? value : {};
|
|
2654
|
+
}
|
|
2655
|
+
function getRunStatusColor(status) {
|
|
2656
|
+
switch (status) {
|
|
2657
|
+
case "completed":
|
|
2658
|
+
case "success":
|
|
2659
|
+
case "succeeded":
|
|
2660
|
+
return "green";
|
|
2661
|
+
case "running":
|
|
2662
|
+
case "pending":
|
|
2663
|
+
case "queued":
|
|
2664
|
+
return "blue";
|
|
2665
|
+
case "failed":
|
|
2666
|
+
case "error":
|
|
2667
|
+
case "cancelled":
|
|
2668
|
+
return "red";
|
|
2669
|
+
default:
|
|
2670
|
+
return "gray";
|
|
2671
|
+
}
|
|
2672
|
+
}
|
|
2673
|
+
function getRunInput(run) {
|
|
2674
|
+
const payload = asRecord3(run.payload);
|
|
2675
|
+
return run.input ?? run.inputs ?? payload.input ?? payload.inputs;
|
|
2676
|
+
}
|
|
2677
|
+
function hasRunInput(run) {
|
|
2678
|
+
const input = getRunInput(run);
|
|
2679
|
+
return input !== void 0 && input !== null;
|
|
2680
|
+
}
|
|
2681
|
+
function sanitizeStepInput(value, _capabilityKey) {
|
|
2682
|
+
return value;
|
|
2683
|
+
}
|
|
2684
|
+
function getDefaultStepInput(list, action) {
|
|
2685
|
+
return asRecord3(action?.defaultInput?.(list));
|
|
2686
|
+
}
|
|
2687
|
+
function getInitialStepInput(list, action) {
|
|
2688
|
+
return getDefaultStepInput(list, action);
|
|
2689
|
+
}
|
|
2690
|
+
function mergeStepRunInput(list, action, inputAtSubmit) {
|
|
2691
|
+
return {
|
|
2692
|
+
...getDefaultStepInput(list, action),
|
|
2693
|
+
...inputAtSubmit
|
|
2694
|
+
};
|
|
2695
|
+
}
|
|
2696
|
+
var EMPTY_SELECTION2 = {
|
|
2697
|
+
selectedCompanyIds: [],
|
|
2698
|
+
selectedContactIds: []
|
|
2699
|
+
};
|
|
2623
2700
|
function getStageStatus(entry) {
|
|
2624
2701
|
if (!entry || (entry.total ?? 0) === 0) return "not-started";
|
|
2625
2702
|
if ((entry.error ?? 0) > 0) return "errors";
|
|
@@ -2673,6 +2750,8 @@ function StageNode({
|
|
|
2673
2750
|
const total = entry?.total ?? 0;
|
|
2674
2751
|
const attempted = entry?.attempted ?? 0;
|
|
2675
2752
|
const success = entry?.success ?? 0;
|
|
2753
|
+
const done = entry ? entry.success + entry.noResult + entry.skipped + entry.other : 0;
|
|
2754
|
+
const summary = entry ? status === "complete" ? `${done}/${total} done` : status === "errors" ? `${entry.error} failed` : `${attempted}/${total} started` : "Not started";
|
|
2676
2755
|
const tooltipLines = entry ? [
|
|
2677
2756
|
`${attempted} / ${total} attempted`,
|
|
2678
2757
|
`${success} success`,
|
|
@@ -2709,7 +2788,7 @@ function StageNode({
|
|
|
2709
2788
|
boxShadow: `0 0 0 4px ${colors.ring}`,
|
|
2710
2789
|
transition: "all var(--duration-normal) var(--easing)"
|
|
2711
2790
|
},
|
|
2712
|
-
children: /* @__PURE__ */ jsx(
|
|
2791
|
+
children: /* @__PURE__ */ jsx(Box, { style: { color: colors.fg, lineHeight: 1, display: "flex", alignItems: "center" }, children: status === "complete" ? "OK" : index + 1 })
|
|
2713
2792
|
}
|
|
2714
2793
|
) }),
|
|
2715
2794
|
/* @__PURE__ */ jsxs(Stack, { gap: 2, align: "center", style: { minWidth: 0, maxWidth: "100%" }, children: [
|
|
@@ -2728,7 +2807,7 @@ function StageNode({
|
|
|
2728
2807
|
children: label
|
|
2729
2808
|
}
|
|
2730
2809
|
),
|
|
2731
|
-
/* @__PURE__ */ jsx(Text, { size: "xs", style: { color: "var(--color-text-subtle)", fontVariantNumeric: "tabular-nums" }, children:
|
|
2810
|
+
/* @__PURE__ */ jsx(Text, { size: "xs", style: { color: "var(--color-text-subtle)", fontVariantNumeric: "tabular-nums" }, children: summary })
|
|
2732
2811
|
] })
|
|
2733
2812
|
]
|
|
2734
2813
|
}
|
|
@@ -2774,14 +2853,14 @@ function PipelineStepper({
|
|
|
2774
2853
|
) });
|
|
2775
2854
|
}
|
|
2776
2855
|
function PipelineStagesCard({ list, progress }) {
|
|
2777
|
-
const plannedSteps = list
|
|
2856
|
+
const plannedSteps = resolveBuildPlanSteps(list);
|
|
2778
2857
|
const templateLabel = list.metadata.buildPlanSnapshot?.templateLabel;
|
|
2779
2858
|
const combinedByStage = { ...progress.byCompanyStage, ...progress.byContactStage };
|
|
2780
2859
|
const hasAnyContent = plannedSteps.length > 0 || Object.keys(combinedByStage).length > 0;
|
|
2781
2860
|
return /* @__PURE__ */ jsx(Card, { withBorder: true, children: /* @__PURE__ */ jsxs(Stack, { gap: "md", children: [
|
|
2782
2861
|
/* @__PURE__ */ jsxs(Group, { justify: "space-between", align: "center", children: [
|
|
2783
2862
|
/* @__PURE__ */ jsxs(Stack, { gap: 2, children: [
|
|
2784
|
-
/* @__PURE__ */ jsx(Title, { order: 5, children: "
|
|
2863
|
+
/* @__PURE__ */ jsx(Title, { order: 5, children: "List Build Progress" }),
|
|
2785
2864
|
templateLabel && /* @__PURE__ */ jsxs(Text, { size: "xs", c: "dimmed", children: [
|
|
2786
2865
|
"Template: ",
|
|
2787
2866
|
templateLabel
|
|
@@ -2893,7 +2972,7 @@ function OverviewTab({ list, progress }) {
|
|
|
2893
2972
|
{
|
|
2894
2973
|
icon: /* @__PURE__ */ jsx(IconBuilding, { size: 16 }),
|
|
2895
2974
|
title: "Overview",
|
|
2896
|
-
description: "
|
|
2975
|
+
description: "Build status and source details for this list.",
|
|
2897
2976
|
children: [
|
|
2898
2977
|
/* @__PURE__ */ jsxs(SimpleGrid, { cols: { base: 1, sm: 2 }, children: [
|
|
2899
2978
|
/* @__PURE__ */ jsx(StatCard, { label: "Companies", value: progress.totalCompanies, icon: IconBuilding }),
|
|
@@ -3003,12 +3082,21 @@ function BuildStepProgressBar({ step }) {
|
|
|
3003
3082
|
function getDisplayStep(steps, recommendedStep) {
|
|
3004
3083
|
return recommendedStep ?? steps.find((step) => step.status !== "complete") ?? steps[steps.length - 1] ?? null;
|
|
3005
3084
|
}
|
|
3085
|
+
function getBuildTabDescription(steps, currentStep) {
|
|
3086
|
+
if (!steps.length) return "No build steps are available for this list.";
|
|
3087
|
+
if (steps.every((step) => step.status === "complete")) return "List build complete.";
|
|
3088
|
+
if (!currentStep) return "No build steps need attention right now.";
|
|
3089
|
+
if (currentStep.status === "ready") return `${currentStep.label} is ready to run.`;
|
|
3090
|
+
if (currentStep.status === "failed") return `${currentStep.label} needs attention.`;
|
|
3091
|
+
return `${currentStep.label} is waiting on earlier work.`;
|
|
3092
|
+
}
|
|
3006
3093
|
function BuildTab({
|
|
3007
3094
|
list,
|
|
3008
3095
|
steps,
|
|
3009
3096
|
recommendedStep,
|
|
3010
3097
|
onRunStep,
|
|
3011
3098
|
onRetryStep,
|
|
3099
|
+
onViewRunLog,
|
|
3012
3100
|
onViewRuns
|
|
3013
3101
|
}) {
|
|
3014
3102
|
const [selectedStepId, setSelectedStepId] = useState(null);
|
|
@@ -3041,7 +3129,7 @@ function BuildTab({
|
|
|
3041
3129
|
if (recentRuns.length > 0) {
|
|
3042
3130
|
const lastInput = getRunInput(recentRuns[0]);
|
|
3043
3131
|
if (lastInput) {
|
|
3044
|
-
setStepInputFormState(sanitizeStepInput(
|
|
3132
|
+
setStepInputFormState(sanitizeStepInput(asRecord3(lastInput)));
|
|
3045
3133
|
setStepInputResetKey((k) => k + 1);
|
|
3046
3134
|
}
|
|
3047
3135
|
}
|
|
@@ -3070,16 +3158,21 @@ function BuildTab({
|
|
|
3070
3158
|
onRunStep(selectedStep, submittedInput);
|
|
3071
3159
|
};
|
|
3072
3160
|
const loadRecentRunInput = (run) => {
|
|
3073
|
-
setStepInputFormState(sanitizeStepInput(
|
|
3161
|
+
setStepInputFormState(sanitizeStepInput(asRecord3(getRunInput(run))));
|
|
3074
3162
|
setStepInputResetKey((k) => k + 1);
|
|
3075
3163
|
setActiveRightColumnTab("configuration");
|
|
3076
3164
|
};
|
|
3165
|
+
const openRecentRunLog = (run) => {
|
|
3166
|
+
const resourceId = run.resourceId ?? selectedResourceId;
|
|
3167
|
+
if (!resourceId) return;
|
|
3168
|
+
onViewRunLog(resourceId, run.executionId);
|
|
3169
|
+
};
|
|
3077
3170
|
return /* @__PURE__ */ jsx(
|
|
3078
3171
|
TabSection,
|
|
3079
3172
|
{
|
|
3080
3173
|
icon: /* @__PURE__ */ jsx(IconBolt, { size: 16 }),
|
|
3081
3174
|
title: "Build",
|
|
3082
|
-
description:
|
|
3175
|
+
description: getBuildTabDescription(steps, currentStep),
|
|
3083
3176
|
children: /* @__PURE__ */ jsxs(SimpleGrid, { cols: { base: 1, md: 2 }, spacing: "md", children: [
|
|
3084
3177
|
/* @__PURE__ */ jsx(Card, { withBorder: true, style: { height: "100%", display: "flex", flexDirection: "column" }, children: /* @__PURE__ */ jsx(Stack, { gap: "xs", style: { flex: 1, minHeight: 0 }, children: steps.map((step, index) => {
|
|
3085
3178
|
const isCurrent = currentStep?.id === step.id;
|
|
@@ -3169,7 +3262,7 @@ function BuildTab({
|
|
|
3169
3262
|
schema: stepSchema,
|
|
3170
3263
|
layout: stepLayout,
|
|
3171
3264
|
value: stepInputFormState,
|
|
3172
|
-
onChange: (v) => handleStepInputChange(
|
|
3265
|
+
onChange: (v) => handleStepInputChange(asRecord3(v) ?? {}),
|
|
3173
3266
|
disabled: !canRunSelectedAction
|
|
3174
3267
|
},
|
|
3175
3268
|
`${selectedResourceId ?? "none"}-main-${stepInputResetKey}`
|
|
@@ -3182,7 +3275,7 @@ function BuildTab({
|
|
|
3182
3275
|
schema: stepSchema,
|
|
3183
3276
|
layout: stepLayout,
|
|
3184
3277
|
value: stepInputFormState,
|
|
3185
|
-
onChange: (v) => handleStepInputChange(
|
|
3278
|
+
onChange: (v) => handleStepInputChange(asRecord3(v) ?? {}),
|
|
3186
3279
|
disabled: !canRunSelectedAction
|
|
3187
3280
|
},
|
|
3188
3281
|
`${selectedResourceId ?? "none"}-advanced-${stepInputResetKey}`
|
|
@@ -3192,27 +3285,48 @@ function BuildTab({
|
|
|
3192
3285
|
/* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", fw: 700, tt: "uppercase", children: "Recent runs" }),
|
|
3193
3286
|
recentRunsQuery.isFetching ? /* @__PURE__ */ jsx(Loader, { size: "xs" }) : null
|
|
3194
3287
|
] }),
|
|
3195
|
-
!recentRuns.length && !recentRunsQuery.isLoading ? /* @__PURE__ */ jsx(Text, { size: "sm", c: "dimmed", children: "No runs yet for this step." }) : /* @__PURE__ */ jsx(Stack, { gap: 4, children: recentRuns.map((run) =>
|
|
3196
|
-
|
|
3197
|
-
|
|
3198
|
-
|
|
3199
|
-
|
|
3200
|
-
|
|
3201
|
-
|
|
3202
|
-
|
|
3203
|
-
|
|
3204
|
-
|
|
3288
|
+
!recentRuns.length && !recentRunsQuery.isLoading ? /* @__PURE__ */ jsx(Text, { size: "sm", c: "dimmed", children: "No runs yet for this step." }) : /* @__PURE__ */ jsx(Stack, { gap: 4, children: recentRuns.map((run) => {
|
|
3289
|
+
const canUseSettings = hasRunInput(run);
|
|
3290
|
+
return /* @__PURE__ */ jsx(
|
|
3291
|
+
Box,
|
|
3292
|
+
{
|
|
3293
|
+
style: {
|
|
3294
|
+
border: "1px solid var(--color-border)",
|
|
3295
|
+
borderRadius: 8,
|
|
3296
|
+
padding: "8px 10px",
|
|
3297
|
+
width: "100%"
|
|
3298
|
+
},
|
|
3299
|
+
children: /* @__PURE__ */ jsxs(Group, { justify: "space-between", gap: "xs", wrap: "nowrap", children: [
|
|
3300
|
+
/* @__PURE__ */ jsx(
|
|
3301
|
+
UnstyledButton,
|
|
3302
|
+
{
|
|
3303
|
+
onClick: () => openRecentRunLog(run),
|
|
3304
|
+
style: { flex: 1, minWidth: 0, textAlign: "left" },
|
|
3305
|
+
children: /* @__PURE__ */ jsxs(Group, { justify: "space-between", gap: "xs", wrap: "nowrap", children: [
|
|
3306
|
+
/* @__PURE__ */ jsxs(Stack, { gap: 2, style: { minWidth: 0 }, children: [
|
|
3307
|
+
/* @__PURE__ */ jsx(Text, { size: "sm", fw: 600, truncate: true, children: formatDateTime4(run.createdAt) }),
|
|
3308
|
+
/* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", ff: "monospace", truncate: true, children: run.executionId })
|
|
3309
|
+
] }),
|
|
3310
|
+
/* @__PURE__ */ jsx(Badge, { size: "sm", variant: "light", color: getRunStatusColor(run.status), children: run.status })
|
|
3311
|
+
] })
|
|
3312
|
+
}
|
|
3313
|
+
),
|
|
3314
|
+
/* @__PURE__ */ jsx(Tooltip, { label: "Use this run's settings", children: /* @__PURE__ */ jsx(
|
|
3315
|
+
Button,
|
|
3316
|
+
{
|
|
3317
|
+
size: "xs",
|
|
3318
|
+
variant: "subtle",
|
|
3319
|
+
leftSection: /* @__PURE__ */ jsx(IconSettings, { size: 12 }),
|
|
3320
|
+
disabled: !canUseSettings,
|
|
3321
|
+
onClick: () => loadRecentRunInput(run),
|
|
3322
|
+
children: "Use settings"
|
|
3323
|
+
}
|
|
3324
|
+
) })
|
|
3325
|
+
] })
|
|
3205
3326
|
},
|
|
3206
|
-
|
|
3207
|
-
|
|
3208
|
-
|
|
3209
|
-
/* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", ff: "monospace", truncate: true, children: run.executionId })
|
|
3210
|
-
] }),
|
|
3211
|
-
/* @__PURE__ */ jsx(Badge, { size: "sm", variant: "light", color: getRunStatusColor(run.status), children: run.status })
|
|
3212
|
-
] })
|
|
3213
|
-
},
|
|
3214
|
-
run.executionId
|
|
3215
|
-
)) })
|
|
3327
|
+
run.executionId
|
|
3328
|
+
);
|
|
3329
|
+
}) })
|
|
3216
3330
|
] }) : /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: "No runs available for this step." }),
|
|
3217
3331
|
action: /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
3218
3332
|
stepInputError ? /* @__PURE__ */ jsx(Alert, { color: "red", icon: /* @__PURE__ */ jsx(IconAlertCircle, { size: 16 }), variant: "light", children: stepInputError }) : null,
|
|
@@ -3285,14 +3399,14 @@ function MembersTab({
|
|
|
3285
3399
|
] }) }),
|
|
3286
3400
|
/* @__PURE__ */ jsx(Table.Tbody, { children: contacts.map((contact) => {
|
|
3287
3401
|
const handleRowClick = () => onMemberClick?.(contact.id, "contact");
|
|
3288
|
-
const
|
|
3402
|
+
const memberStage = displayMemberStageFor(contact, "contact");
|
|
3289
3403
|
return /* @__PURE__ */ jsxs(Table.Tr, { onClick: handleRowClick, style: { cursor: "pointer" }, children: [
|
|
3290
3404
|
/* @__PURE__ */ jsx(Table.Td, { children: /* @__PURE__ */ jsx(Text, { fw: 500, children: contactDisplayName(contact.firstName, contact.lastName) }) }),
|
|
3291
3405
|
/* @__PURE__ */ jsx(Table.Td, { children: contact.email }),
|
|
3292
3406
|
/* @__PURE__ */ jsx(Table.Td, { children: contact.title ?? "\u2014" }),
|
|
3293
3407
|
/* @__PURE__ */ jsx(Table.Td, { children: contact.company?.name ?? "\u2014" }),
|
|
3294
3408
|
/* @__PURE__ */ jsx(Table.Td, { children: /* @__PURE__ */ jsx(Badge, { size: "sm", variant: "light", color: getStatusColor4(contact.status), children: contact.status }) }),
|
|
3295
|
-
/* @__PURE__ */ jsx(Table.Td, { children:
|
|
3409
|
+
/* @__PURE__ */ jsx(Table.Td, { children: memberStage ? /* @__PURE__ */ jsx(Badge, { size: "sm", variant: "dot", color: getMemberStateColor2(memberStage.key), children: memberStage.label }) : /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: "\u2014" }) }),
|
|
3296
3410
|
/* @__PURE__ */ jsx(Table.Td, { children: formatDateTime4(contact.createdAt) })
|
|
3297
3411
|
] }, contact.id);
|
|
3298
3412
|
}) })
|
|
@@ -3309,14 +3423,14 @@ function MembersTab({
|
|
|
3309
3423
|
] }) }),
|
|
3310
3424
|
/* @__PURE__ */ jsx(Table.Tbody, { children: companies.map((company) => {
|
|
3311
3425
|
const handleRowClick = () => onMemberClick?.(company.id, "company");
|
|
3312
|
-
const
|
|
3426
|
+
const memberStage = displayMemberStageFor(company, "company");
|
|
3313
3427
|
return /* @__PURE__ */ jsxs(Table.Tr, { onClick: handleRowClick, style: { cursor: "pointer" }, children: [
|
|
3314
3428
|
/* @__PURE__ */ jsx(Table.Td, { children: /* @__PURE__ */ jsx(Text, { fw: 500, children: company.name }) }),
|
|
3315
3429
|
/* @__PURE__ */ jsx(Table.Td, { children: company.domain ?? "\u2014" }),
|
|
3316
3430
|
/* @__PURE__ */ jsx(Table.Td, { children: company.segment ?? "\u2014" }),
|
|
3317
3431
|
/* @__PURE__ */ jsx(Table.Td, { children: company.contactCount }),
|
|
3318
3432
|
/* @__PURE__ */ jsx(Table.Td, { children: /* @__PURE__ */ jsx(Badge, { size: "sm", variant: "light", color: getStatusColor4(company.status), children: company.status }) }),
|
|
3319
|
-
/* @__PURE__ */ jsx(Table.Td, { children:
|
|
3433
|
+
/* @__PURE__ */ jsx(Table.Td, { children: memberStage ? /* @__PURE__ */ jsx(Badge, { size: "sm", variant: "dot", color: getMemberStateColor2(memberStage.key), children: memberStage.label }) : /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: "\u2014" }) }),
|
|
3320
3434
|
/* @__PURE__ */ jsx(Table.Td, { children: formatDateTime4(company.createdAt) })
|
|
3321
3435
|
] }, company.id);
|
|
3322
3436
|
}) })
|
|
@@ -3353,6 +3467,7 @@ function LeadGenListDetailPage({ listId }) {
|
|
|
3353
3467
|
};
|
|
3354
3468
|
const listQuery = useList(listId);
|
|
3355
3469
|
const progressQuery = useListProgress(listId);
|
|
3470
|
+
const executionsQuery = useListExecutions(listId);
|
|
3356
3471
|
const deleteListMutation = useDeleteList();
|
|
3357
3472
|
const [deleteModalOpen, setDeleteModalOpen] = useState(false);
|
|
3358
3473
|
const [runModalOpen, setRunModalOpen] = useState(false);
|
|
@@ -3370,8 +3485,8 @@ function LeadGenListDetailPage({ listId }) {
|
|
|
3370
3485
|
};
|
|
3371
3486
|
});
|
|
3372
3487
|
}, [actions, pendingStepRunInput]);
|
|
3373
|
-
const isLoading = listQuery.isLoading || progressQuery.isLoading;
|
|
3374
|
-
const error = listQuery.error ?? progressQuery.error;
|
|
3488
|
+
const isLoading = listQuery.isLoading || progressQuery.isLoading || executionsQuery.isLoading;
|
|
3489
|
+
const error = listQuery.error ?? progressQuery.error ?? executionsQuery.error;
|
|
3375
3490
|
const backButton = /* @__PURE__ */ jsx(
|
|
3376
3491
|
Button,
|
|
3377
3492
|
{
|
|
@@ -3423,8 +3538,10 @@ function LeadGenListDetailPage({ listId }) {
|
|
|
3423
3538
|
}
|
|
3424
3539
|
const list = listQuery.data;
|
|
3425
3540
|
const progress = progressQuery.data;
|
|
3541
|
+
const executions = executionsQuery.data ?? [];
|
|
3542
|
+
const businessProgress = deriveBusinessProgress(list, progress, actions, executions);
|
|
3426
3543
|
const currentBuildTemplateLabel = list.metadata.buildPlanSnapshot?.templateLabel ?? "Default lead generation";
|
|
3427
|
-
const buildResolution = resolveBuildState(list,
|
|
3544
|
+
const buildResolution = resolveBuildState(list, businessProgress, actions);
|
|
3428
3545
|
const buildSteps = buildResolution.steps;
|
|
3429
3546
|
const recommendedBuildStep = buildResolution.recommendedStep;
|
|
3430
3547
|
const openRunModal = (resourceId) => {
|
|
@@ -3505,8 +3622,8 @@ function LeadGenListDetailPage({ listId }) {
|
|
|
3505
3622
|
/* @__PURE__ */ jsx(Tabs.Tab, { value: "build", leftSection: /* @__PURE__ */ jsx(IconBolt, { size: 14 }), children: "Build" }),
|
|
3506
3623
|
/* @__PURE__ */ jsx(Tabs.Tab, { value: "runs", leftSection: /* @__PURE__ */ jsx(IconPlayerPlay, { size: 14 }), children: "Runs" })
|
|
3507
3624
|
] }),
|
|
3508
|
-
/* @__PURE__ */ jsx(Tabs.Panel, { value: "overview", pt: "sm", children: /* @__PURE__ */ jsx(OverviewTab, { list, progress }) }),
|
|
3509
|
-
/* @__PURE__ */ jsx(Tabs.Panel, { value: "members", pt: "sm", children: /* @__PURE__ */ jsx(MembersTab, { listId, progress, onMemberClick: handleMemberClick }) }),
|
|
3625
|
+
/* @__PURE__ */ jsx(Tabs.Panel, { value: "overview", pt: "sm", children: /* @__PURE__ */ jsx(OverviewTab, { list, progress: businessProgress }) }),
|
|
3626
|
+
/* @__PURE__ */ jsx(Tabs.Panel, { value: "members", pt: "sm", children: /* @__PURE__ */ jsx(MembersTab, { listId, progress: businessProgress, onMemberClick: handleMemberClick }) }),
|
|
3510
3627
|
/* @__PURE__ */ jsx(Tabs.Panel, { value: "build", pt: "sm", children: /* @__PURE__ */ jsx(
|
|
3511
3628
|
BuildTab,
|
|
3512
3629
|
{
|
|
@@ -3515,6 +3632,13 @@ function LeadGenListDetailPage({ listId }) {
|
|
|
3515
3632
|
recommendedStep: recommendedBuildStep,
|
|
3516
3633
|
onRunStep: openStepRun,
|
|
3517
3634
|
onRetryStep: openStepRun,
|
|
3635
|
+
onViewRunLog: (resourceId, executionId) => {
|
|
3636
|
+
void navigate({
|
|
3637
|
+
to: "/operations/resources/workflow/$workflowId",
|
|
3638
|
+
params: { workflowId: resourceId },
|
|
3639
|
+
search: { exec: executionId }
|
|
3640
|
+
});
|
|
3641
|
+
},
|
|
3518
3642
|
onViewRuns: (resourceId) => {
|
|
3519
3643
|
setRunsResourceFilter(resourceId);
|
|
3520
3644
|
setActiveTab("runs");
|
|
@@ -3936,4 +4060,4 @@ function LeadGenContactsPage() {
|
|
|
3936
4060
|
] }) });
|
|
3937
4061
|
}
|
|
3938
4062
|
|
|
3939
|
-
export { CompanyDetailModal, ContactDetailModal, LEAD_GEN_ITEMS, LEAD_GEN_ROUTE_LINKS, LeadGenCompaniesPage, LeadGenContactsPage, LeadGenListDetailPage, LeadGenListsPage, LeadGenOverviewPage, LeadGenRouteShell, LeadGenSidebar, LeadGenSidebarMiddle, LeadGenSidebarTop, ListBuilderIndexPage, ListBuilderPage, RunWorkflowModal, StepConfigForm, TabSection, formatDate, getEnrichmentColor, getEnrichmentStatus, getStateKeyColor, getStatusColor, leadGenManifest, useDeleteLists };
|
|
4063
|
+
export { CompanyDetailModal, ContactDetailModal, LEAD_GEN_ITEMS, LEAD_GEN_ROUTE_LINKS, LeadGenCompaniesPage, LeadGenContactsPage, LeadGenListDetailPage, LeadGenListsPage, LeadGenOverviewPage, LeadGenRouteShell, LeadGenSidebar, LeadGenSidebarMiddle, LeadGenSidebarTop, ListBuilderIndexPage, ListBuilderPage, ORPHAN_STAGE_ORDER, RunWorkflowModal, StepConfigForm, TabSection, deriveBusinessProgress, formatDate, getEnrichmentColor, getEnrichmentStatus, getStateKeyColor, getStatusColor, getStepActionLabel, leadGenManifest, resolveBuildPlanSteps, resolveBuildState, sortStageKeys, useDeleteLists };
|