@elevasis/ui 2.28.1 → 2.30.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 +54 -0
- package/dist/app/index.js +10 -10
- package/dist/auth/index.js +4 -4
- package/dist/charts/index.d.ts +2 -1
- package/dist/charts/index.js +8 -8
- package/dist/{chunk-HNN3QALL.js → chunk-2DIYILF7.js} +9 -8
- package/dist/{chunk-XTVZFT7U.js → chunk-2Q2JQSQO.js} +1 -1
- package/dist/{chunk-UOHOKDKL.js → chunk-3GV5NHSS.js} +1052 -209
- package/dist/{chunk-PBNIW7KV.js → chunk-3MDNBHVB.js} +140 -9
- package/dist/{chunk-K4Q5QUHZ.js → chunk-4FZYEEPK.js} +6 -6
- package/dist/{chunk-MJMFIWEB.js → chunk-4SY6BTVZ.js} +2 -2
- package/dist/{chunk-HLFFKKT3.js → chunk-4VQ2PXMI.js} +14 -14
- package/dist/{chunk-WKJ47GIW.js → chunk-533DUEQY.js} +1 -1
- package/dist/{chunk-N63RKL3L.js → chunk-6EFVZV6X.js} +394 -311
- package/dist/{chunk-V3HUIZJX.js → chunk-6IXOKUBC.js} +1 -1
- package/dist/{chunk-GJXAAYZ3.js → chunk-6WXDE5LZ.js} +1 -1
- package/dist/{chunk-VKMNWHTL.js → chunk-6YT4IKJ7.js} +3 -3
- package/dist/{chunk-ZPXV5KI3.js → chunk-7E3FUTND.js} +1 -1
- package/dist/{chunk-YNYGUVGW.js → chunk-A7B7HLDF.js} +11 -10
- package/dist/{chunk-NU5FNTOB.js → chunk-AKOD52HS.js} +84 -15
- package/dist/{chunk-CT5IR4ZA.js → chunk-CLUP5H3C.js} +6 -9
- package/dist/{chunk-MYEOTM7D.js → chunk-CN2HC4D4.js} +5 -1
- package/dist/{chunk-ROSMICXG.js → chunk-CXY7FMUM.js} +35 -20
- package/dist/{chunk-HOIT677G.js → chunk-HUJCU55S.js} +1 -1
- package/dist/{chunk-SRNIHB7Y.js → chunk-HXZQWMKE.js} +1 -2
- package/dist/{chunk-M6OJ43NL.js → chunk-HYLERWRO.js} +99 -30
- package/dist/{chunk-XBMCDGHA.js → chunk-IKQ42WHU.js} +1 -1
- package/dist/{chunk-GESXCQWY.js → chunk-JA5ECJJB.js} +1 -1
- package/dist/{chunk-KU7ZDWQ7.js → chunk-JBWJ6WHZ.js} +1 -1
- package/dist/{chunk-MCRKFDKB.js → chunk-JKTPRYGV.js} +5 -5
- package/dist/{chunk-5WWZXCS5.js → chunk-KJ3QUBNU.js} +9 -2
- package/dist/{chunk-3HCTCMAS.js → chunk-LRZFLK2F.js} +3 -3
- package/dist/chunk-NITGGYH2.js +476 -0
- package/dist/{chunk-VMJVQAFZ.js → chunk-OAVTMITG.js} +1 -1
- package/dist/{chunk-TVJROM2V.js → chunk-P5WYW2GI.js} +58 -37
- package/dist/{chunk-5R27NFOI.js → chunk-SBCIB5TZ.js} +6 -27
- package/dist/{chunk-AYSO5A3R.js → chunk-SKXXT3E2.js} +4 -4
- package/dist/{chunk-MZCDRBSI.js → chunk-T2PAD63Y.js} +12 -12
- package/dist/{chunk-LH4GPYDX.js → chunk-T5Z7G2J2.js} +19 -3
- package/dist/{chunk-WFTNY755.js → chunk-VKIZUUPM.js} +1 -1
- package/dist/{chunk-S66IQSSR.js → chunk-WF227UBV.js} +1 -1
- package/dist/components/chat/index.d.ts +2 -1
- package/dist/components/chat/index.js +1 -1
- package/dist/components/index.js +42 -42
- package/dist/components/navigation/index.js +8 -8
- package/dist/features/auth/index.js +5 -5
- package/dist/features/crm/index.js +21 -21
- package/dist/features/dashboard/index.js +22 -22
- package/dist/features/delivery/index.js +21 -21
- package/dist/features/knowledge/index.js +45 -31
- package/dist/features/lead-gen/index.d.ts +116 -2
- package/dist/features/lead-gen/index.js +22 -22
- package/dist/features/monitoring/index.js +23 -23
- package/dist/features/monitoring/requests/index.js +20 -20
- package/dist/features/operations/index.js +27 -27
- package/dist/features/settings/index.js +22 -22
- package/dist/hooks/delivery/index.js +3 -3
- package/dist/hooks/index.d.ts +263 -4
- package/dist/hooks/index.js +20 -20
- package/dist/hooks/published.d.ts +263 -4
- package/dist/hooks/published.js +20 -20
- package/dist/index.d.ts +378 -10
- package/dist/index.js +21 -21
- package/dist/initialization/index.js +4 -4
- package/dist/knowledge/index.d.ts +55 -1
- package/dist/knowledge/index.js +102 -2
- package/dist/organization/index.js +4 -4
- package/dist/profile/index.js +2 -2
- package/dist/provider/ElevasisServiceContext.d.ts +11 -5
- package/dist/provider/ElevasisServiceContext.js +1 -1
- package/dist/provider/index.d.ts +119 -5
- package/dist/provider/index.js +17 -17
- package/dist/provider/published.d.ts +119 -5
- package/dist/provider/published.js +13 -13
- package/dist/test-utils/index.d.ts +3 -0
- package/dist/test-utils/index.js +30 -6
- package/dist/theme/index.js +3 -3
- package/dist/theme/presets/index.js +1 -1
- 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-JS7VBTC4.js +0 -250
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { DEFAULT_ORGANIZATION_MODEL_PROSPECTING, PROSPECTING_STEPS } from './chunk-
|
|
1
|
+
import { DEFAULT_ORGANIZATION_MODEL_PROSPECTING, PROSPECTING_STEPS } from './chunk-NITGGYH2.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,18 +6,19 @@ 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, useCredentials, useVerifyCredential, useInFlightExecutions, useListRecords, useCompany, useContact, useExecutionSSE, useListMembers, useListMember, useTransitionListMember, useDeriveActions, useArtifacts } from './chunk-6EFVZV6X.js';
|
|
10
|
+
import { showApiErrorNotification, showSuccessNotification } from './chunk-T2PAD63Y.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-AKOD52HS.js';
|
|
13
13
|
import { SubshellContentContainer } from './chunk-TKAYX2SP.js';
|
|
14
14
|
import { useRouterContext } from './chunk-Q7DJKLEN.js';
|
|
15
|
-
import {
|
|
16
|
-
import {
|
|
17
|
-
import {
|
|
15
|
+
import { isStepStartedContext, isStepCompletedContext, isStepFailedContext } from './chunk-KRWALB24.js';
|
|
16
|
+
import { useElevasisServices } from './chunk-KJ3QUBNU.js';
|
|
17
|
+
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, Progress } from '@mantine/core';
|
|
18
|
+
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, IconCircleCheck, IconCircleDot, IconTerminal2, IconProgressCheck, IconMail, IconUser, IconDatabase } from '@tabler/icons-react';
|
|
18
19
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
19
20
|
import { Link, useNavigate, useSearch } from '@tanstack/react-router';
|
|
20
|
-
import { useState, useRef, useMemo, useEffect, Fragment as Fragment$1 } from 'react';
|
|
21
|
+
import { useState, useRef, useMemo, useEffect, Fragment as Fragment$1, useCallback } from 'react';
|
|
21
22
|
import { useForm } from '@mantine/form';
|
|
22
23
|
import { zod4Resolver } from 'mantine-form-zod-resolver';
|
|
23
24
|
import { useQueryClient, useMutation } from '@tanstack/react-query';
|
|
@@ -84,13 +85,25 @@ function createBuildPlanSnapshotFromTemplateId(templateId) {
|
|
|
84
85
|
primaryEntity: step.primaryEntity,
|
|
85
86
|
outputs: [...step.outputs],
|
|
86
87
|
stageKey: step.stageKey,
|
|
88
|
+
recordsStageKey: step.recordsStageKey ?? step.stageKey,
|
|
89
|
+
recordSourceStageKey: step.recordSourceStageKey ?? step.recordsStageKey ?? step.stageKey,
|
|
87
90
|
dependencyMode: step.dependencyMode,
|
|
88
91
|
capabilityKey: step.capabilityKey,
|
|
89
92
|
defaultBatchSize: step.defaultBatchSize,
|
|
90
93
|
maxBatchSize: step.maxBatchSize
|
|
91
94
|
};
|
|
92
95
|
if (step.description) snapshotStep.description = step.description;
|
|
96
|
+
if (step.recordEntity) snapshotStep.recordEntity = step.recordEntity;
|
|
93
97
|
if (step.dependsOn?.length) snapshotStep.dependsOn = [...step.dependsOn];
|
|
98
|
+
if (step.credentialRequirements?.length) {
|
|
99
|
+
snapshotStep.credentialRequirements = step.credentialRequirements.map((requirement) => ({ ...requirement }));
|
|
100
|
+
}
|
|
101
|
+
if (step.recordColumns) {
|
|
102
|
+
snapshotStep.recordColumns = {
|
|
103
|
+
...step.recordColumns.company ? { company: step.recordColumns.company.map((column) => ({ ...column })) } : {},
|
|
104
|
+
...step.recordColumns.contact ? { contact: step.recordColumns.contact.map((column) => ({ ...column })) } : {}
|
|
105
|
+
};
|
|
106
|
+
}
|
|
94
107
|
return snapshotStep;
|
|
95
108
|
})
|
|
96
109
|
};
|
|
@@ -586,7 +599,7 @@ function ContactDetailModal({
|
|
|
586
599
|
] }) : null });
|
|
587
600
|
}
|
|
588
601
|
function useDeleteLists() {
|
|
589
|
-
const { apiRequest,
|
|
602
|
+
const { apiRequest, workOSOrganizationId } = useElevasisServices();
|
|
590
603
|
const queryClient = useQueryClient();
|
|
591
604
|
return useMutation({
|
|
592
605
|
mutationFn: async (listIds) => {
|
|
@@ -601,8 +614,8 @@ function useDeleteLists() {
|
|
|
601
614
|
);
|
|
602
615
|
},
|
|
603
616
|
onSuccess: () => {
|
|
604
|
-
queryClient.invalidateQueries({ queryKey: acquisitionListKeys.list(
|
|
605
|
-
queryClient.invalidateQueries({ queryKey: acquisitionListKeys.telemetry(
|
|
617
|
+
queryClient.invalidateQueries({ queryKey: acquisitionListKeys.list(workOSOrganizationId) });
|
|
618
|
+
queryClient.invalidateQueries({ queryKey: acquisitionListKeys.telemetry(workOSOrganizationId) });
|
|
606
619
|
showSuccessNotification("Lists deleted");
|
|
607
620
|
},
|
|
608
621
|
onError: (error) => {
|
|
@@ -1369,6 +1382,253 @@ function ListMemberDrawer({ memberId, memberKind, listId, onClose }) {
|
|
|
1369
1382
|
}
|
|
1370
1383
|
);
|
|
1371
1384
|
}
|
|
1385
|
+
function formatEventTime(timestamp) {
|
|
1386
|
+
return new Date(timestamp).toLocaleTimeString("en-US", {
|
|
1387
|
+
hour12: false,
|
|
1388
|
+
hour: "2-digit",
|
|
1389
|
+
minute: "2-digit",
|
|
1390
|
+
second: "2-digit"
|
|
1391
|
+
});
|
|
1392
|
+
}
|
|
1393
|
+
function formatId(executionId) {
|
|
1394
|
+
return executionId.length > 10 ? `${executionId.slice(0, 8)}...` : executionId;
|
|
1395
|
+
}
|
|
1396
|
+
function getLogLevelColor(level) {
|
|
1397
|
+
switch (level) {
|
|
1398
|
+
case "error":
|
|
1399
|
+
return "red";
|
|
1400
|
+
case "warn":
|
|
1401
|
+
return "yellow";
|
|
1402
|
+
case "debug":
|
|
1403
|
+
return "gray";
|
|
1404
|
+
default:
|
|
1405
|
+
return "blue";
|
|
1406
|
+
}
|
|
1407
|
+
}
|
|
1408
|
+
function getStepStatusColor(status) {
|
|
1409
|
+
switch (status) {
|
|
1410
|
+
case "failed":
|
|
1411
|
+
return "red";
|
|
1412
|
+
case "done":
|
|
1413
|
+
return "green";
|
|
1414
|
+
default:
|
|
1415
|
+
return "blue";
|
|
1416
|
+
}
|
|
1417
|
+
}
|
|
1418
|
+
function getStepStatusLabel(status) {
|
|
1419
|
+
switch (status) {
|
|
1420
|
+
case "failed":
|
|
1421
|
+
return "Failed";
|
|
1422
|
+
case "done":
|
|
1423
|
+
return "Done";
|
|
1424
|
+
default:
|
|
1425
|
+
return "Running";
|
|
1426
|
+
}
|
|
1427
|
+
}
|
|
1428
|
+
function getEventColor(event) {
|
|
1429
|
+
switch (event.type) {
|
|
1430
|
+
case "new-execution":
|
|
1431
|
+
return "blue";
|
|
1432
|
+
case "execution-complete":
|
|
1433
|
+
return event.data.success ? "green" : "red";
|
|
1434
|
+
case "log":
|
|
1435
|
+
return getLogLevelColor(event.data.log.level);
|
|
1436
|
+
default:
|
|
1437
|
+
return "gray";
|
|
1438
|
+
}
|
|
1439
|
+
}
|
|
1440
|
+
function getEventLabel(event) {
|
|
1441
|
+
switch (event.type) {
|
|
1442
|
+
case "new-execution":
|
|
1443
|
+
return "Execution started";
|
|
1444
|
+
case "execution-complete":
|
|
1445
|
+
return event.data.success ? "Execution completed" : "Execution failed";
|
|
1446
|
+
case "log":
|
|
1447
|
+
return event.data.log.message;
|
|
1448
|
+
default:
|
|
1449
|
+
return "Stream connected";
|
|
1450
|
+
}
|
|
1451
|
+
}
|
|
1452
|
+
function hasExecutionId(event) {
|
|
1453
|
+
return event.type !== "connected" && typeof event.executionId === "string" && event.executionId.length > 0;
|
|
1454
|
+
}
|
|
1455
|
+
function toTimelineEvents(events) {
|
|
1456
|
+
return events.filter(hasExecutionId).map((event) => ({
|
|
1457
|
+
executionId: event.executionId,
|
|
1458
|
+
timestamp: event.timestamp,
|
|
1459
|
+
label: getEventLabel(event),
|
|
1460
|
+
color: getEventColor(event),
|
|
1461
|
+
detail: event.type === "execution-complete" ? event.data.error : void 0
|
|
1462
|
+
})).sort((a, b) => b.timestamp - a.timestamp).slice(0, 5);
|
|
1463
|
+
}
|
|
1464
|
+
function collectStepStatuses(events, streamingLogs) {
|
|
1465
|
+
const statuses = /* @__PURE__ */ new Map();
|
|
1466
|
+
const applyLog = (executionId, log) => {
|
|
1467
|
+
const context = log.context;
|
|
1468
|
+
if (!context || context.type !== "workflow") return;
|
|
1469
|
+
if (!("stepId" in context)) return;
|
|
1470
|
+
let status = null;
|
|
1471
|
+
if (isStepStartedContext(context)) status = "running";
|
|
1472
|
+
if (isStepCompletedContext(context)) status = "done";
|
|
1473
|
+
if (isStepFailedContext(context)) status = "failed";
|
|
1474
|
+
if (!status) return;
|
|
1475
|
+
statuses.set(executionId, {
|
|
1476
|
+
executionId,
|
|
1477
|
+
stepId: context.stepId,
|
|
1478
|
+
status,
|
|
1479
|
+
timestamp: log.timestamp,
|
|
1480
|
+
message: log.message
|
|
1481
|
+
});
|
|
1482
|
+
};
|
|
1483
|
+
events.forEach((event) => {
|
|
1484
|
+
if (event.type === "log") applyLog(event.executionId, event.data.log);
|
|
1485
|
+
});
|
|
1486
|
+
streamingLogs.forEach((logs, executionId) => {
|
|
1487
|
+
logs.forEach((log) => applyLog(executionId, log));
|
|
1488
|
+
});
|
|
1489
|
+
return Array.from(statuses.values()).sort((a, b) => b.timestamp - a.timestamp);
|
|
1490
|
+
}
|
|
1491
|
+
function getExecutionId(execution) {
|
|
1492
|
+
return "executionId" in execution ? execution.executionId : execution.id;
|
|
1493
|
+
}
|
|
1494
|
+
function getInFlightExecutions(data) {
|
|
1495
|
+
if (Array.isArray(data)) return data;
|
|
1496
|
+
if (data && typeof data === "object" && "executions" in data) {
|
|
1497
|
+
const executions = data.executions;
|
|
1498
|
+
return Array.isArray(executions) ? executions : [];
|
|
1499
|
+
}
|
|
1500
|
+
return [];
|
|
1501
|
+
}
|
|
1502
|
+
function getStageProgress(progress, stageKey) {
|
|
1503
|
+
return progress?.byCompanyStage[stageKey] ?? progress?.byContactStage[stageKey];
|
|
1504
|
+
}
|
|
1505
|
+
function getStageLabel(stageKey) {
|
|
1506
|
+
return LEAD_GEN_STAGE_CATALOG[stageKey]?.label ?? stageKey;
|
|
1507
|
+
}
|
|
1508
|
+
function getDoneCount(stageProgress) {
|
|
1509
|
+
return stageProgress?.attempted ?? 0;
|
|
1510
|
+
}
|
|
1511
|
+
function LeadGenLiveStatusPanel({
|
|
1512
|
+
listId,
|
|
1513
|
+
resourceId,
|
|
1514
|
+
stageKey,
|
|
1515
|
+
stepLabel,
|
|
1516
|
+
enabled = true,
|
|
1517
|
+
onRunningChange
|
|
1518
|
+
}) {
|
|
1519
|
+
const sse = useExecutionSSE(resourceId, {
|
|
1520
|
+
enabled: enabled && Boolean(resourceId),
|
|
1521
|
+
listId
|
|
1522
|
+
});
|
|
1523
|
+
const inFlightQuery = useInFlightExecutions(resourceId, {
|
|
1524
|
+
enabled: enabled && Boolean(resourceId),
|
|
1525
|
+
limit: 5,
|
|
1526
|
+
refetchInterval: enabled && Boolean(resourceId) ? 2e3 : false
|
|
1527
|
+
});
|
|
1528
|
+
const inFlightExecutions = useMemo(() => getInFlightExecutions(inFlightQuery.data), [inFlightQuery.data]);
|
|
1529
|
+
const activeExecutionIds = useMemo(() => {
|
|
1530
|
+
const ids = new Set(sse.liveExecutions);
|
|
1531
|
+
inFlightExecutions.forEach((execution) => {
|
|
1532
|
+
const executionId = getExecutionId(execution);
|
|
1533
|
+
if (executionId) ids.add(executionId);
|
|
1534
|
+
});
|
|
1535
|
+
return Array.from(ids);
|
|
1536
|
+
}, [inFlightExecutions, sse.liveExecutions]);
|
|
1537
|
+
const running = enabled && activeExecutionIds.length > 0;
|
|
1538
|
+
const [showCompletedActivity, setShowCompletedActivity] = useState(false);
|
|
1539
|
+
const progressQuery = useListProgress(listId, {
|
|
1540
|
+
enabled: enabled && Boolean(listId),
|
|
1541
|
+
refetchInterval: running ? 2e3 : false
|
|
1542
|
+
});
|
|
1543
|
+
useEffect(() => {
|
|
1544
|
+
onRunningChange?.(running);
|
|
1545
|
+
}, [onRunningChange, running]);
|
|
1546
|
+
const stepStatuses = useMemo(
|
|
1547
|
+
() => collectStepStatuses(sse.events, sse.streamingLogs),
|
|
1548
|
+
[sse.events, sse.streamingLogs]
|
|
1549
|
+
);
|
|
1550
|
+
const latestStepStatus = stepStatuses[0];
|
|
1551
|
+
const lastEvents = useMemo(() => toTimelineEvents(sse.events), [sse.events]);
|
|
1552
|
+
const stageProgress = getStageProgress(progressQuery.data, stageKey);
|
|
1553
|
+
const doneCount = getDoneCount(stageProgress);
|
|
1554
|
+
const totalCount = stageProgress?.total ?? 0;
|
|
1555
|
+
const failed = Boolean(sse.error) || sse.events.some((event) => event.type === "execution-complete" && !event.data.success);
|
|
1556
|
+
const latestEvent = sse.latestEvent;
|
|
1557
|
+
useEffect(() => {
|
|
1558
|
+
if (running || failed || sse.error) {
|
|
1559
|
+
setShowCompletedActivity(true);
|
|
1560
|
+
return;
|
|
1561
|
+
}
|
|
1562
|
+
if (latestEvent?.type !== "execution-complete") return;
|
|
1563
|
+
setShowCompletedActivity(true);
|
|
1564
|
+
const timeoutId = window.setTimeout(() => setShowCompletedActivity(false), 1e4);
|
|
1565
|
+
return () => window.clearTimeout(timeoutId);
|
|
1566
|
+
}, [failed, latestEvent, running, sse.error]);
|
|
1567
|
+
const hasActivity = activeExecutionIds.length > 0 || sse.streamingLogs.size > 0 || showCompletedActivity || Boolean(sse.error);
|
|
1568
|
+
if (!enabled || !hasActivity && !sse.error && !failed) {
|
|
1569
|
+
return null;
|
|
1570
|
+
}
|
|
1571
|
+
return /* @__PURE__ */ jsx(Paper, { withBorder: true, p: "sm", children: /* @__PURE__ */ jsxs(Stack, { gap: "xs", children: [
|
|
1572
|
+
/* @__PURE__ */ jsx(
|
|
1573
|
+
CardHeader,
|
|
1574
|
+
{
|
|
1575
|
+
icon: /* @__PURE__ */ jsx(IconTerminal2, { size: 16 }),
|
|
1576
|
+
title: stepLabel ? `${stepLabel} status` : "Live status",
|
|
1577
|
+
rightSection: /* @__PURE__ */ jsxs(Group, { gap: 6, children: [
|
|
1578
|
+
/* @__PURE__ */ jsx(
|
|
1579
|
+
Badge,
|
|
1580
|
+
{
|
|
1581
|
+
size: "xs",
|
|
1582
|
+
variant: "light",
|
|
1583
|
+
color: sse.connected ? "green" : running ? "yellow" : "gray",
|
|
1584
|
+
leftSection: sse.connected ? /* @__PURE__ */ jsx(IconCircleCheck, { size: 9 }) : /* @__PURE__ */ jsx(IconCircleDot, { size: 9 }),
|
|
1585
|
+
children: sse.connected ? "Connected" : running ? "Reconnecting" : "Idle"
|
|
1586
|
+
}
|
|
1587
|
+
),
|
|
1588
|
+
running ? /* @__PURE__ */ jsxs(Badge, { size: "xs", variant: "filled", color: "blue", leftSection: /* @__PURE__ */ jsx(IconPlayerPlay, { size: 9 }), children: [
|
|
1589
|
+
activeExecutionIds.length,
|
|
1590
|
+
" running"
|
|
1591
|
+
] }) : null
|
|
1592
|
+
] })
|
|
1593
|
+
}
|
|
1594
|
+
),
|
|
1595
|
+
sse.error ? /* @__PURE__ */ jsx(Alert, { icon: /* @__PURE__ */ jsx(IconAlertCircle, { size: 14 }), color: "red", variant: "light", p: "xs", children: /* @__PURE__ */ jsx(Text, { size: "xs", children: sse.error }) }) : null,
|
|
1596
|
+
activeExecutionIds.length > 0 ? /* @__PURE__ */ jsx(Group, { gap: 6, children: activeExecutionIds.map((executionId) => /* @__PURE__ */ jsx(Badge, { size: "xs", variant: "light", color: "blue", ff: "monospace", children: formatId(executionId) }, executionId)) }) : null,
|
|
1597
|
+
/* @__PURE__ */ jsxs(Box, { p: "xs", bg: "var(--surface-primary-subtle)", style: { borderRadius: "var(--mantine-radius-sm)" }, children: [
|
|
1598
|
+
/* @__PURE__ */ jsxs(Group, { justify: "space-between", gap: "xs", wrap: "nowrap", children: [
|
|
1599
|
+
/* @__PURE__ */ jsxs(Group, { gap: 6, wrap: "nowrap", style: { minWidth: 0 }, children: [
|
|
1600
|
+
/* @__PURE__ */ jsx(IconProgressCheck, { size: 14 }),
|
|
1601
|
+
/* @__PURE__ */ jsx(Text, { size: "xs", fw: 600, truncate: "end", children: getStageLabel(stageKey) })
|
|
1602
|
+
] }),
|
|
1603
|
+
/* @__PURE__ */ jsxs(Text, { size: "xs", c: "dimmed", ff: "monospace", children: [
|
|
1604
|
+
doneCount,
|
|
1605
|
+
"/",
|
|
1606
|
+
totalCount,
|
|
1607
|
+
" done"
|
|
1608
|
+
] })
|
|
1609
|
+
] }),
|
|
1610
|
+
/* @__PURE__ */ jsx(
|
|
1611
|
+
Progress,
|
|
1612
|
+
{
|
|
1613
|
+
mt: 6,
|
|
1614
|
+
size: "xs",
|
|
1615
|
+
value: totalCount > 0 ? doneCount / totalCount * 100 : 0,
|
|
1616
|
+
color: stageProgress && stageProgress.error > 0 ? "red" : "blue"
|
|
1617
|
+
}
|
|
1618
|
+
)
|
|
1619
|
+
] }),
|
|
1620
|
+
latestStepStatus ? /* @__PURE__ */ jsxs(Group, { gap: 6, wrap: "nowrap", children: [
|
|
1621
|
+
/* @__PURE__ */ jsx(Badge, { size: "xs", color: getStepStatusColor(latestStepStatus.status), variant: "light", children: getStepStatusLabel(latestStepStatus.status) }),
|
|
1622
|
+
/* @__PURE__ */ jsx(Text, { size: "xs", fw: 500, truncate: "end", children: latestStepStatus.stepId }),
|
|
1623
|
+
/* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", truncate: "end", style: { flex: 1 }, children: latestStepStatus.message })
|
|
1624
|
+
] }) : running ? /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: "Waiting for workflow step events." }) : null,
|
|
1625
|
+
lastEvents.length > 0 ? /* @__PURE__ */ jsx(Stack, { gap: 4, children: lastEvents.map((event) => /* @__PURE__ */ jsxs(Group, { gap: 6, wrap: "nowrap", children: [
|
|
1626
|
+
/* @__PURE__ */ jsx(Badge, { size: "xs", variant: "dot", color: event.color, miw: 68, children: formatEventTime(event.timestamp) }),
|
|
1627
|
+
/* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", ff: "monospace", miw: 62, children: formatId(event.executionId) }),
|
|
1628
|
+
/* @__PURE__ */ jsx(Text, { size: "xs", truncate: "end", style: { flex: 1 }, children: event.detail ?? event.label })
|
|
1629
|
+
] }, `${event.executionId}-${event.timestamp}-${event.label}`)) }) : null
|
|
1630
|
+
] }) });
|
|
1631
|
+
}
|
|
1372
1632
|
var panelStyle = {
|
|
1373
1633
|
flex: 1,
|
|
1374
1634
|
minHeight: 0,
|
|
@@ -1377,6 +1637,7 @@ var panelStyle = {
|
|
|
1377
1637
|
};
|
|
1378
1638
|
function StepDetailRightColumn({
|
|
1379
1639
|
configuration,
|
|
1640
|
+
records,
|
|
1380
1641
|
advanced,
|
|
1381
1642
|
runs,
|
|
1382
1643
|
action,
|
|
@@ -1397,7 +1658,7 @@ function StepDetailRightColumn({
|
|
|
1397
1658
|
{
|
|
1398
1659
|
value: activeTab,
|
|
1399
1660
|
onChange: (value) => {
|
|
1400
|
-
if (value === "configuration" || value === "advanced" || value === "runs") {
|
|
1661
|
+
if (value === "configuration" || value === "records" || value === "advanced" || value === "runs") {
|
|
1401
1662
|
onTabChange(value);
|
|
1402
1663
|
}
|
|
1403
1664
|
},
|
|
@@ -1410,10 +1671,12 @@ function StepDetailRightColumn({
|
|
|
1410
1671
|
children: [
|
|
1411
1672
|
/* @__PURE__ */ jsxs(Tabs.List, { children: [
|
|
1412
1673
|
/* @__PURE__ */ jsx(Tabs.Tab, { value: "configuration", children: "Configuration" }),
|
|
1674
|
+
/* @__PURE__ */ jsx(Tabs.Tab, { value: "records", children: "Records" }),
|
|
1413
1675
|
/* @__PURE__ */ jsx(Tabs.Tab, { value: "advanced", children: "Advanced" }),
|
|
1414
1676
|
/* @__PURE__ */ jsx(Tabs.Tab, { value: "runs", children: "Runs" })
|
|
1415
1677
|
] }),
|
|
1416
1678
|
/* @__PURE__ */ jsx(Tabs.Panel, { value: "configuration", style: panelStyle, children: configuration }),
|
|
1679
|
+
/* @__PURE__ */ jsx(Tabs.Panel, { value: "records", style: panelStyle, children: records ?? /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: "No records view configured for this step." }) }),
|
|
1417
1680
|
/* @__PURE__ */ jsx(Tabs.Panel, { value: "advanced", style: panelStyle, children: advanced ?? /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: "No advanced settings for this step." }) }),
|
|
1418
1681
|
/* @__PURE__ */ jsx(Tabs.Panel, { value: "runs", style: panelStyle, children: runs })
|
|
1419
1682
|
]
|
|
@@ -1513,6 +1776,12 @@ var STAGE_COLOR_SETS = {
|
|
|
1513
1776
|
border: "color-mix(in srgb, var(--color-border) 70%, var(--color-primary))",
|
|
1514
1777
|
text: "var(--color-text)"
|
|
1515
1778
|
},
|
|
1779
|
+
crawled: {
|
|
1780
|
+
accent: "color-mix(in srgb, var(--color-primary) 70%, var(--color-text-subtle))",
|
|
1781
|
+
background: "color-mix(in srgb, var(--color-primary) 9%, transparent)",
|
|
1782
|
+
border: "color-mix(in srgb, var(--color-border) 72%, var(--color-primary))",
|
|
1783
|
+
text: "var(--color-text)"
|
|
1784
|
+
},
|
|
1516
1785
|
extracted: {
|
|
1517
1786
|
accent: "color-mix(in srgb, var(--color-primary) 78%, var(--color-success))",
|
|
1518
1787
|
background: "color-mix(in srgb, var(--color-primary) 10%, transparent)",
|
|
@@ -1628,7 +1897,7 @@ function buildLaneStages({
|
|
|
1628
1897
|
})
|
|
1629
1898
|
);
|
|
1630
1899
|
}
|
|
1631
|
-
function
|
|
1900
|
+
function getStageProgress2(progress, stageKey, entity) {
|
|
1632
1901
|
const stageProgress = entity === "company" ? progress.byCompanyStage[stageKey] : progress.byContactStage[stageKey];
|
|
1633
1902
|
const total = stageProgress?.total ?? (entity === "company" ? progress.totalCompanies : progress.totalMembers);
|
|
1634
1903
|
return {
|
|
@@ -1746,7 +2015,7 @@ function TimelineLane({
|
|
|
1746
2015
|
position: "relative"
|
|
1747
2016
|
},
|
|
1748
2017
|
children: stages.map((stage, index) => {
|
|
1749
|
-
const counts =
|
|
2018
|
+
const counts = getStageProgress2(progress, stage.key, entity);
|
|
1750
2019
|
const accent = getLeadGenStageColorVar(stage.key);
|
|
1751
2020
|
const completion = Math.round(percent(counts.success, counts.total));
|
|
1752
2021
|
const attempted = Math.round(percent(counts.attempted, counts.total));
|
|
@@ -2416,7 +2685,7 @@ function sortStageKeys(keys) {
|
|
|
2416
2685
|
return oa - ob || a.localeCompare(b);
|
|
2417
2686
|
});
|
|
2418
2687
|
}
|
|
2419
|
-
function
|
|
2688
|
+
function getStageProgress3(progress, step) {
|
|
2420
2689
|
return step.primaryEntity === "company" ? progress.byCompanyStage[step.stageKey] : progress.byContactStage[step.stageKey];
|
|
2421
2690
|
}
|
|
2422
2691
|
function getEntityTotal(progress, entity) {
|
|
@@ -2434,11 +2703,16 @@ function normalizeBuildPlanStep(step) {
|
|
|
2434
2703
|
primaryEntity: step.primaryEntity,
|
|
2435
2704
|
outputs: step.outputs,
|
|
2436
2705
|
stageKey: step.stageKey,
|
|
2706
|
+
recordEntity: step.recordEntity,
|
|
2707
|
+
recordsStageKey: step.recordsStageKey,
|
|
2708
|
+
recordSourceStageKey: step.recordSourceStageKey,
|
|
2437
2709
|
dependsOn: step.dependsOn,
|
|
2438
2710
|
dependencyMode: step.dependencyMode,
|
|
2439
2711
|
capabilityKey: step.capabilityKey,
|
|
2440
2712
|
defaultBatchSize: step.defaultBatchSize,
|
|
2441
2713
|
maxBatchSize: step.maxBatchSize,
|
|
2714
|
+
recordColumns: step.recordColumns,
|
|
2715
|
+
credentialRequirements: step.credentialRequirements,
|
|
2442
2716
|
emptyBlockedText: fallback?.emptyBlockedText ?? "Complete prerequisite build steps before this action can run."
|
|
2443
2717
|
};
|
|
2444
2718
|
}
|
|
@@ -2563,7 +2837,7 @@ function getStepRecommendedAction(step, action, kind) {
|
|
|
2563
2837
|
function deriveBuildStepStates(list, progress, actions) {
|
|
2564
2838
|
const byStepId = /* @__PURE__ */ new Map();
|
|
2565
2839
|
for (const step of resolveBuildPlanSteps(list)) {
|
|
2566
|
-
const stageProgress =
|
|
2840
|
+
const stageProgress = getStageProgress3(progress, step);
|
|
2567
2841
|
const entityTotal = getEntityTotal(progress, step.primaryEntity);
|
|
2568
2842
|
const prerequisites = getPrerequisiteSteps(step, byStepId);
|
|
2569
2843
|
const hasDependencies = (step.dependsOn?.length ?? 0) > 0;
|
|
@@ -2652,6 +2926,101 @@ function displayMemberStageFor(row, kind) {
|
|
|
2652
2926
|
function asRecord3(value) {
|
|
2653
2927
|
return value && typeof value === "object" && !Array.isArray(value) ? value : {};
|
|
2654
2928
|
}
|
|
2929
|
+
function valueAtPath(source, path) {
|
|
2930
|
+
return path.split(".").reduce((current, segment) => {
|
|
2931
|
+
if (!current || typeof current !== "object") return void 0;
|
|
2932
|
+
return current[segment];
|
|
2933
|
+
}, source);
|
|
2934
|
+
}
|
|
2935
|
+
function compactText(value) {
|
|
2936
|
+
if (value === null || value === void 0 || value === "") return "-";
|
|
2937
|
+
if (Array.isArray(value)) {
|
|
2938
|
+
if (!value.length) return "-";
|
|
2939
|
+
return value.map((item) => {
|
|
2940
|
+
if (item && typeof item === "object") {
|
|
2941
|
+
const labelled = item;
|
|
2942
|
+
return String(labelled.name ?? labelled.label ?? labelled.title ?? labelled.id ?? JSON.stringify(item));
|
|
2943
|
+
}
|
|
2944
|
+
return String(item);
|
|
2945
|
+
}).join(", ");
|
|
2946
|
+
}
|
|
2947
|
+
if (typeof value === "object") return JSON.stringify(value);
|
|
2948
|
+
return String(value);
|
|
2949
|
+
}
|
|
2950
|
+
function getRecordDisplayName(row) {
|
|
2951
|
+
if (row.entity === "company") return row.company?.name ?? "Company";
|
|
2952
|
+
const contact = row.contact;
|
|
2953
|
+
const full = [contact?.firstName, contact?.lastName].filter(Boolean).join(" ").trim();
|
|
2954
|
+
return full || contact?.email || "Contact";
|
|
2955
|
+
}
|
|
2956
|
+
function getRecordColumnSource(row) {
|
|
2957
|
+
if (row.entity === "company") {
|
|
2958
|
+
return {
|
|
2959
|
+
...row,
|
|
2960
|
+
company: row.company ? {
|
|
2961
|
+
...row.company,
|
|
2962
|
+
enrichmentData: row.enrichmentData,
|
|
2963
|
+
processingState: row.processingState
|
|
2964
|
+
} : null
|
|
2965
|
+
};
|
|
2966
|
+
}
|
|
2967
|
+
return {
|
|
2968
|
+
...row,
|
|
2969
|
+
contact: row.contact ? {
|
|
2970
|
+
...row.contact,
|
|
2971
|
+
name: getRecordDisplayName(row),
|
|
2972
|
+
enrichmentData: row.enrichmentData,
|
|
2973
|
+
processingState: row.processingState
|
|
2974
|
+
} : null
|
|
2975
|
+
};
|
|
2976
|
+
}
|
|
2977
|
+
function getStageEntry(row, stageKey) {
|
|
2978
|
+
const entry = valueAtPath(row.processingState, stageKey);
|
|
2979
|
+
return asRecord3(entry);
|
|
2980
|
+
}
|
|
2981
|
+
function getRecordStageStatus(row, stageKey) {
|
|
2982
|
+
const status = getStageEntry(row, stageKey).status;
|
|
2983
|
+
return typeof status === "string" ? status : "pending";
|
|
2984
|
+
}
|
|
2985
|
+
function getStageFailureReason(row, stageKey) {
|
|
2986
|
+
const data = asRecord3(getStageEntry(row, stageKey).data);
|
|
2987
|
+
const error = data.error ?? data.reason ?? data.failureReason ?? data.disqualifiedReason;
|
|
2988
|
+
return compactText(error);
|
|
2989
|
+
}
|
|
2990
|
+
function getRecordStatusColor(status) {
|
|
2991
|
+
switch (status) {
|
|
2992
|
+
case "success":
|
|
2993
|
+
return "green";
|
|
2994
|
+
case "error":
|
|
2995
|
+
case "failed":
|
|
2996
|
+
return "red";
|
|
2997
|
+
case "skipped":
|
|
2998
|
+
case "no_result":
|
|
2999
|
+
return "yellow";
|
|
3000
|
+
case "pending":
|
|
3001
|
+
return "gray";
|
|
3002
|
+
default:
|
|
3003
|
+
return "blue";
|
|
3004
|
+
}
|
|
3005
|
+
}
|
|
3006
|
+
function renderRecordValue(value, column) {
|
|
3007
|
+
if (value === null || value === void 0 || value === "") {
|
|
3008
|
+
return /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: "-" });
|
|
3009
|
+
}
|
|
3010
|
+
switch (column.renderType) {
|
|
3011
|
+
case "badge":
|
|
3012
|
+
return /* @__PURE__ */ jsx(Badge, { size: "sm", variant: "light", color: column.badgeColor ?? getRecordStatusColor(String(value)), children: compactText(value) });
|
|
3013
|
+
case "datetime":
|
|
3014
|
+
return compactText(typeof value === "string" ? formatDateTime4(value) : value);
|
|
3015
|
+
case "count":
|
|
3016
|
+
return Array.isArray(value) ? value.length : compactText(value);
|
|
3017
|
+
case "json":
|
|
3018
|
+
return /* @__PURE__ */ jsx(Text, { size: "xs", lineClamp: 2, children: compactText(value) });
|
|
3019
|
+
case "text":
|
|
3020
|
+
default:
|
|
3021
|
+
return /* @__PURE__ */ jsx(Text, { size: "sm", lineClamp: 2, children: compactText(value) });
|
|
3022
|
+
}
|
|
3023
|
+
}
|
|
2655
3024
|
function getRunStatusColor(status) {
|
|
2656
3025
|
switch (status) {
|
|
2657
3026
|
case "completed":
|
|
@@ -3090,20 +3459,393 @@ function getBuildTabDescription(steps, currentStep) {
|
|
|
3090
3459
|
if (currentStep.status === "failed") return `${currentStep.label} needs attention.`;
|
|
3091
3460
|
return `${currentStep.label} is waiting on earlier work.`;
|
|
3092
3461
|
}
|
|
3462
|
+
var RECORDS_PAGE_SIZE = 25;
|
|
3463
|
+
var EXPORT_WORKFLOW_ID = "lgn-06-export-list-workflow";
|
|
3464
|
+
function setValueAtInputPath(source, path, value) {
|
|
3465
|
+
const segments = path.split(".").filter(Boolean);
|
|
3466
|
+
if (!segments.length) return source;
|
|
3467
|
+
const next = { ...source };
|
|
3468
|
+
let cursor = next;
|
|
3469
|
+
segments.forEach((segment, index) => {
|
|
3470
|
+
if (index === segments.length - 1) {
|
|
3471
|
+
cursor[segment] = value;
|
|
3472
|
+
return;
|
|
3473
|
+
}
|
|
3474
|
+
const current = cursor[segment];
|
|
3475
|
+
const child = current && typeof current === "object" && !Array.isArray(current) ? { ...current } : {};
|
|
3476
|
+
cursor[segment] = child;
|
|
3477
|
+
cursor = child;
|
|
3478
|
+
});
|
|
3479
|
+
return next;
|
|
3480
|
+
}
|
|
3481
|
+
function credentialMatchesRequirement(credential, requirement) {
|
|
3482
|
+
const provider = requirement.provider.toLowerCase();
|
|
3483
|
+
const credentialProvider = credential.provider?.toLowerCase() ?? "";
|
|
3484
|
+
const credentialType = credential.type.toLowerCase();
|
|
3485
|
+
const credentialName = credential.name.toLowerCase();
|
|
3486
|
+
if (credentialProvider === provider || credentialType === provider || credentialName.startsWith(`${provider}-`) || credentialName.includes(`-${provider}`) || credentialName.includes(`${provider}-`)) {
|
|
3487
|
+
return true;
|
|
3488
|
+
}
|
|
3489
|
+
return credentialType === requirement.credentialType;
|
|
3490
|
+
}
|
|
3491
|
+
function getMatchingCredentials(credentials, requirement) {
|
|
3492
|
+
return credentials.filter((credential) => credentialMatchesRequirement(credential, requirement));
|
|
3493
|
+
}
|
|
3494
|
+
function getSelectedCredential(credentials, selections, requirement) {
|
|
3495
|
+
const selectedId = selections[requirement.key];
|
|
3496
|
+
return credentials.find((credential) => credential.id === selectedId) ?? null;
|
|
3497
|
+
}
|
|
3498
|
+
function getClickUpRequirement(step) {
|
|
3499
|
+
return step.credentialRequirements?.find((requirement) => requirement.provider === "clickup") ?? null;
|
|
3500
|
+
}
|
|
3501
|
+
function filterCredentialRequirementFields(layout, requirements) {
|
|
3502
|
+
if (!layout || requirements.length === 0) return layout;
|
|
3503
|
+
const credentialInputPaths = new Set(requirements.map((requirement) => requirement.inputPath).filter(Boolean));
|
|
3504
|
+
if (!credentialInputPaths.size) return layout;
|
|
3505
|
+
const filterSection = (section) => {
|
|
3506
|
+
const fields = section.fields.filter((field) => !credentialInputPaths.has(field.path));
|
|
3507
|
+
return fields.length > 0 ? { ...section, fields } : null;
|
|
3508
|
+
};
|
|
3509
|
+
return {
|
|
3510
|
+
...layout,
|
|
3511
|
+
sections: layout.sections.map(filterSection).filter((section) => section !== null),
|
|
3512
|
+
advanced: layout.advanced ? filterSection(layout.advanced) ?? void 0 : void 0
|
|
3513
|
+
};
|
|
3514
|
+
}
|
|
3515
|
+
function hasMainConfigFields(layout) {
|
|
3516
|
+
return Boolean(layout?.sections.some((section) => section.fields.length > 0));
|
|
3517
|
+
}
|
|
3518
|
+
function hasAdvancedConfigFields(layout) {
|
|
3519
|
+
return Boolean(layout?.advanced?.fields.length);
|
|
3520
|
+
}
|
|
3521
|
+
function formatCredentialVerificationDetails(details) {
|
|
3522
|
+
if (!details) return null;
|
|
3523
|
+
const entries = Object.entries(details).filter(([, value]) => value !== null && value !== void 0 && value !== "").slice(0, 4);
|
|
3524
|
+
if (!entries.length) return null;
|
|
3525
|
+
return entries.map(([key, value]) => `${key}: ${compactText(value)}`).join(" | ");
|
|
3526
|
+
}
|
|
3527
|
+
function CredentialRequirementsPanel({
|
|
3528
|
+
requirements,
|
|
3529
|
+
credentials,
|
|
3530
|
+
credentialsLoading,
|
|
3531
|
+
selections,
|
|
3532
|
+
verificationByCredentialId,
|
|
3533
|
+
verifyingCredentialId,
|
|
3534
|
+
onSelect,
|
|
3535
|
+
onVerify
|
|
3536
|
+
}) {
|
|
3537
|
+
if (!requirements.length) return null;
|
|
3538
|
+
return /* @__PURE__ */ jsxs(Stack, { gap: "xs", children: [
|
|
3539
|
+
/* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", fw: 700, tt: "uppercase", children: "Credentials" }),
|
|
3540
|
+
requirements.map((requirement) => {
|
|
3541
|
+
const matchingCredentials = getMatchingCredentials(credentials, requirement);
|
|
3542
|
+
const selectedCredential = getSelectedCredential(credentials, selections, requirement);
|
|
3543
|
+
const verification = selectedCredential ? verificationByCredentialId[selectedCredential.id] : null;
|
|
3544
|
+
return /* @__PURE__ */ jsxs(Stack, { gap: 6, children: [
|
|
3545
|
+
/* @__PURE__ */ jsxs(Group, { gap: "xs", align: "flex-end", wrap: "nowrap", children: [
|
|
3546
|
+
/* @__PURE__ */ jsx(
|
|
3547
|
+
Select,
|
|
3548
|
+
{
|
|
3549
|
+
label: requirement.label,
|
|
3550
|
+
description: `${requirement.provider} credential for ${requirement.inputPath}`,
|
|
3551
|
+
placeholder: credentialsLoading ? "Loading credentials..." : "Select credential",
|
|
3552
|
+
data: matchingCredentials.map((credential) => ({
|
|
3553
|
+
value: credential.id,
|
|
3554
|
+
label: `${credential.name} (${credential.provider ?? credential.type})`
|
|
3555
|
+
})),
|
|
3556
|
+
value: selectedCredential?.id ?? null,
|
|
3557
|
+
onChange: (credentialId) => {
|
|
3558
|
+
onSelect(requirement, credentials.find((credential) => credential.id === credentialId) ?? null);
|
|
3559
|
+
},
|
|
3560
|
+
required: requirement.required,
|
|
3561
|
+
disabled: credentialsLoading || matchingCredentials.length === 0,
|
|
3562
|
+
style: { flex: 1 }
|
|
3563
|
+
}
|
|
3564
|
+
),
|
|
3565
|
+
/* @__PURE__ */ jsx(
|
|
3566
|
+
Button,
|
|
3567
|
+
{
|
|
3568
|
+
size: "xs",
|
|
3569
|
+
variant: "light",
|
|
3570
|
+
disabled: !selectedCredential,
|
|
3571
|
+
loading: selectedCredential ? verifyingCredentialId === selectedCredential.id : false,
|
|
3572
|
+
onClick: () => selectedCredential && onVerify(selectedCredential),
|
|
3573
|
+
children: "Test credential"
|
|
3574
|
+
}
|
|
3575
|
+
)
|
|
3576
|
+
] }),
|
|
3577
|
+
matchingCredentials.length === 0 ? /* @__PURE__ */ jsx(
|
|
3578
|
+
Alert,
|
|
3579
|
+
{
|
|
3580
|
+
color: requirement.required ? "yellow" : "gray",
|
|
3581
|
+
variant: "light",
|
|
3582
|
+
icon: /* @__PURE__ */ jsx(IconAlertCircle, { size: 16 }),
|
|
3583
|
+
children: /* @__PURE__ */ jsxs(Text, { size: "sm", children: [
|
|
3584
|
+
"No matching ",
|
|
3585
|
+
requirement.provider,
|
|
3586
|
+
" credentials found. Add one in",
|
|
3587
|
+
" ",
|
|
3588
|
+
/* @__PURE__ */ jsx(Text, { component: "a", href: "/settings/credentials", size: "sm", fw: 600, children: "Settings -> Credentials" }),
|
|
3589
|
+
"."
|
|
3590
|
+
] })
|
|
3591
|
+
}
|
|
3592
|
+
) : null,
|
|
3593
|
+
verification ? /* @__PURE__ */ jsx(
|
|
3594
|
+
Alert,
|
|
3595
|
+
{
|
|
3596
|
+
color: verification.status === "success" ? "green" : "red",
|
|
3597
|
+
variant: "light",
|
|
3598
|
+
icon: /* @__PURE__ */ jsx(IconAlertCircle, { size: 16 }),
|
|
3599
|
+
children: /* @__PURE__ */ jsxs(Stack, { gap: 2, children: [
|
|
3600
|
+
/* @__PURE__ */ jsx(Text, { size: "sm", children: verification.message }),
|
|
3601
|
+
verification.checkedAt ? /* @__PURE__ */ jsxs(Text, { size: "xs", c: "dimmed", children: [
|
|
3602
|
+
"Checked ",
|
|
3603
|
+
formatDateTime4(verification.checkedAt)
|
|
3604
|
+
] }) : null,
|
|
3605
|
+
formatCredentialVerificationDetails(verification.details) ? /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: formatCredentialVerificationDetails(verification.details) }) : null
|
|
3606
|
+
] })
|
|
3607
|
+
}
|
|
3608
|
+
) : null
|
|
3609
|
+
] }, requirement.key);
|
|
3610
|
+
})
|
|
3611
|
+
] });
|
|
3612
|
+
}
|
|
3613
|
+
function BuildStepRunningWatcher({
|
|
3614
|
+
resourceId,
|
|
3615
|
+
onRunningChange
|
|
3616
|
+
}) {
|
|
3617
|
+
const inFlightQuery = useInFlightExecutions(resourceId, {
|
|
3618
|
+
enabled: Boolean(resourceId),
|
|
3619
|
+
limit: 5,
|
|
3620
|
+
refetchInterval: 2e3
|
|
3621
|
+
});
|
|
3622
|
+
const isRunning = (inFlightQuery.data?.executions.length ?? 0) > 0;
|
|
3623
|
+
useEffect(() => {
|
|
3624
|
+
onRunningChange(resourceId, isRunning);
|
|
3625
|
+
return () => onRunningChange(resourceId, false);
|
|
3626
|
+
}, [isRunning, onRunningChange, resourceId]);
|
|
3627
|
+
return null;
|
|
3628
|
+
}
|
|
3629
|
+
function StepRecordsPanel({
|
|
3630
|
+
list,
|
|
3631
|
+
step,
|
|
3632
|
+
credentialSelections,
|
|
3633
|
+
credentials,
|
|
3634
|
+
clickupListId
|
|
3635
|
+
}) {
|
|
3636
|
+
const queryClient = useQueryClient();
|
|
3637
|
+
const [page, setPage] = useState(1);
|
|
3638
|
+
const [approvalByCompanyId, setApprovalByCompanyId] = useState({});
|
|
3639
|
+
const [selectedRecord, setSelectedRecord] = useState(null);
|
|
3640
|
+
const recordsStageKey = step.recordSourceStageKey ?? step.recordsStageKey ?? step.stageKey;
|
|
3641
|
+
const recordsEntity = step.recordEntity ?? step.primaryEntity;
|
|
3642
|
+
const columns = step.recordColumns?.[recordsEntity] ?? [];
|
|
3643
|
+
const recordsQuery = useListRecords(list.id, {
|
|
3644
|
+
entity: recordsEntity,
|
|
3645
|
+
stage: recordsStageKey,
|
|
3646
|
+
limit: RECORDS_PAGE_SIZE,
|
|
3647
|
+
offset: (page - 1) * RECORDS_PAGE_SIZE
|
|
3648
|
+
});
|
|
3649
|
+
const exportWorkflowId = step.action?.resourceId ?? EXPORT_WORKFLOW_ID;
|
|
3650
|
+
const exportExecution = useWorkflowExecution({
|
|
3651
|
+
workflowId: exportWorkflowId,
|
|
3652
|
+
listId: list.id
|
|
3653
|
+
});
|
|
3654
|
+
const selectedCompanyId = selectedRecord?.entity === "company" ? selectedRecord.id : "";
|
|
3655
|
+
const selectedContactId = selectedRecord?.entity === "contact" ? selectedRecord.id : "";
|
|
3656
|
+
const selectedCompanyQuery = useCompany(selectedCompanyId);
|
|
3657
|
+
const selectedContactQuery = useContact(selectedContactId);
|
|
3658
|
+
useEffect(() => {
|
|
3659
|
+
setPage(1);
|
|
3660
|
+
setApprovalByCompanyId({});
|
|
3661
|
+
setSelectedRecord(null);
|
|
3662
|
+
}, [step.id]);
|
|
3663
|
+
const rows = recordsQuery.data?.data ?? [];
|
|
3664
|
+
const total = recordsQuery.data?.total ?? 0;
|
|
3665
|
+
const totalPages = Math.max(1, Math.ceil(total / RECORDS_PAGE_SIZE));
|
|
3666
|
+
const isReviewExportStep = step.primaryEntity === "company" && (step.capabilityKey === "lead-gen.export.list" || exportWorkflowId === EXPORT_WORKFLOW_ID);
|
|
3667
|
+
const approvedCompanyIds = Object.entries(approvalByCompanyId).filter(([, status]) => status === "approved").map(([companyId]) => companyId);
|
|
3668
|
+
const rejectedCompanyIds = Object.entries(approvalByCompanyId).filter(([, status]) => status === "rejected").map(([companyId]) => companyId);
|
|
3669
|
+
const clickupRequirement = getClickUpRequirement(step);
|
|
3670
|
+
const clickupCredential = clickupRequirement ? getSelectedCredential(credentials, credentialSelections, clickupRequirement) : null;
|
|
3671
|
+
const isClickUpExportPath = isReviewExportStep && Boolean(clickupRequirement);
|
|
3672
|
+
const normalizedClickupListId = clickupListId.trim();
|
|
3673
|
+
const canExport = approvedCompanyIds.length > 0 && (!isClickUpExportPath || Boolean(clickupCredential) && normalizedClickupListId.length > 0);
|
|
3674
|
+
const exportDisabledReason = approvedCompanyIds.length === 0 ? "Approve at least one company before export." : isClickUpExportPath && !clickupCredential ? "Select a ClickUp credential in Configuration." : isClickUpExportPath && !normalizedClickupListId ? "Enter a ClickUp List ID in Configuration." : null;
|
|
3675
|
+
const setApproval = (companyId, status) => {
|
|
3676
|
+
setApprovalByCompanyId((current) => ({ ...current, [companyId]: status }));
|
|
3677
|
+
};
|
|
3678
|
+
const openRecordDetail = (row) => {
|
|
3679
|
+
if (row.entity === "company") {
|
|
3680
|
+
setSelectedRecord({ entity: "company", id: row.companyId });
|
|
3681
|
+
return;
|
|
3682
|
+
}
|
|
3683
|
+
setSelectedRecord({ entity: "contact", id: row.contactId });
|
|
3684
|
+
};
|
|
3685
|
+
const exportApproved = async () => {
|
|
3686
|
+
try {
|
|
3687
|
+
const result = await exportExecution.execute({
|
|
3688
|
+
input: {
|
|
3689
|
+
listId: list.id,
|
|
3690
|
+
mode: "export",
|
|
3691
|
+
approved: true,
|
|
3692
|
+
...isClickUpExportPath ? {
|
|
3693
|
+
destination: "clickup",
|
|
3694
|
+
clickupCredential: clickupCredential?.name,
|
|
3695
|
+
clickupListId: normalizedClickupListId
|
|
3696
|
+
} : {},
|
|
3697
|
+
approvedCompanyIds,
|
|
3698
|
+
rejectedCompanyIds
|
|
3699
|
+
}
|
|
3700
|
+
});
|
|
3701
|
+
showSuccessNotification(`Export workflow run started: ${result.executionId}`);
|
|
3702
|
+
await queryClient.invalidateQueries({ queryKey: acquisitionListKeys.all });
|
|
3703
|
+
} catch (error) {
|
|
3704
|
+
showApiErrorNotification(error);
|
|
3705
|
+
}
|
|
3706
|
+
};
|
|
3707
|
+
const selectedRecordIsLoading = selectedRecord?.entity === "company" ? selectedCompanyQuery.isLoading : selectedRecord?.entity === "contact" ? selectedContactQuery.isLoading : false;
|
|
3708
|
+
if (!columns.length) {
|
|
3709
|
+
return /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: "No record columns are configured for this step." });
|
|
3710
|
+
}
|
|
3711
|
+
if (recordsQuery.isLoading) {
|
|
3712
|
+
return /* @__PURE__ */ jsx(Center, { p: "md", children: /* @__PURE__ */ jsx(Loader, { size: "sm" }) });
|
|
3713
|
+
}
|
|
3714
|
+
if (recordsQuery.error) {
|
|
3715
|
+
return /* @__PURE__ */ jsx(CenteredErrorState, { error: recordsQuery.error, title: "Failed to load records" });
|
|
3716
|
+
}
|
|
3717
|
+
if (!rows.length) {
|
|
3718
|
+
return /* @__PURE__ */ jsx(Stack, { gap: "xs", children: /* @__PURE__ */ jsxs(Text, { size: "sm", c: "dimmed", children: [
|
|
3719
|
+
"No records found for ",
|
|
3720
|
+
LEAD_GEN_STAGE_CATALOG[recordsStageKey]?.label ?? recordsStageKey,
|
|
3721
|
+
"."
|
|
3722
|
+
] }) });
|
|
3723
|
+
}
|
|
3724
|
+
return /* @__PURE__ */ jsxs(Stack, { gap: "sm", children: [
|
|
3725
|
+
/* @__PURE__ */ jsxs(Group, { justify: "space-between", gap: "xs", children: [
|
|
3726
|
+
/* @__PURE__ */ jsxs(Stack, { gap: 2, children: [
|
|
3727
|
+
/* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", fw: 700, tt: "uppercase", children: "Records" }),
|
|
3728
|
+
/* @__PURE__ */ jsxs(Text, { size: "xs", c: "dimmed", children: [
|
|
3729
|
+
total,
|
|
3730
|
+
" ",
|
|
3731
|
+
recordsEntity,
|
|
3732
|
+
" records from ",
|
|
3733
|
+
LEAD_GEN_STAGE_CATALOG[recordsStageKey]?.label ?? recordsStageKey
|
|
3734
|
+
] })
|
|
3735
|
+
] }),
|
|
3736
|
+
recordsQuery.isFetching ? /* @__PURE__ */ jsx(Loader, { size: "xs" }) : null
|
|
3737
|
+
] }),
|
|
3738
|
+
/* @__PURE__ */ jsx(Box, { style: { overflowX: "auto" }, children: /* @__PURE__ */ jsxs(Table, { highlightOnHover: true, children: [
|
|
3739
|
+
/* @__PURE__ */ jsx(Table.Thead, { children: /* @__PURE__ */ jsxs(Table.Tr, { children: [
|
|
3740
|
+
columns.map((column) => /* @__PURE__ */ jsx(Table.Th, { style: column.width ? { width: column.width } : void 0, children: column.label }, column.key)),
|
|
3741
|
+
/* @__PURE__ */ jsx(Table.Th, { children: "Status" }),
|
|
3742
|
+
/* @__PURE__ */ jsx(Table.Th, { children: "Failure reason" }),
|
|
3743
|
+
isReviewExportStep ? /* @__PURE__ */ jsx(Table.Th, { children: "Approval" }) : null
|
|
3744
|
+
] }) }),
|
|
3745
|
+
/* @__PURE__ */ jsx(Table.Tbody, { children: rows.map((row) => {
|
|
3746
|
+
const columnSource = getRecordColumnSource(row);
|
|
3747
|
+
const status = getRecordStageStatus(row, recordsStageKey);
|
|
3748
|
+
const companyId = row.entity === "company" ? row.companyId : null;
|
|
3749
|
+
return /* @__PURE__ */ jsxs(Table.Tr, { onClick: () => openRecordDetail(row), style: { cursor: "pointer" }, children: [
|
|
3750
|
+
columns.map((column) => /* @__PURE__ */ jsx(Table.Td, { children: renderRecordValue(valueAtPath(columnSource, column.path), column) }, column.key)),
|
|
3751
|
+
/* @__PURE__ */ jsx(Table.Td, { children: /* @__PURE__ */ jsx(Badge, { size: "sm", variant: "light", color: getRecordStatusColor(status), children: status }) }),
|
|
3752
|
+
/* @__PURE__ */ jsx(Table.Td, { children: /* @__PURE__ */ jsx(Text, { size: "sm", lineClamp: 2, children: getStageFailureReason(row, recordsStageKey) }) }),
|
|
3753
|
+
isReviewExportStep ? /* @__PURE__ */ jsx(Table.Td, { children: companyId ? /* @__PURE__ */ jsxs(Group, { gap: 4, wrap: "nowrap", "aria-label": `Approval for ${getRecordDisplayName(row)}`, children: [
|
|
3754
|
+
/* @__PURE__ */ jsx(
|
|
3755
|
+
Button,
|
|
3756
|
+
{
|
|
3757
|
+
size: "compact-xs",
|
|
3758
|
+
variant: approvalByCompanyId[companyId] === "approved" ? "filled" : "light",
|
|
3759
|
+
color: "green",
|
|
3760
|
+
onClick: (event) => {
|
|
3761
|
+
event.stopPropagation();
|
|
3762
|
+
setApproval(companyId, "approved");
|
|
3763
|
+
},
|
|
3764
|
+
children: "Approve"
|
|
3765
|
+
}
|
|
3766
|
+
),
|
|
3767
|
+
/* @__PURE__ */ jsx(
|
|
3768
|
+
Button,
|
|
3769
|
+
{
|
|
3770
|
+
size: "compact-xs",
|
|
3771
|
+
variant: approvalByCompanyId[companyId] === "rejected" ? "filled" : "light",
|
|
3772
|
+
color: "red",
|
|
3773
|
+
onClick: (event) => {
|
|
3774
|
+
event.stopPropagation();
|
|
3775
|
+
setApproval(companyId, "rejected");
|
|
3776
|
+
},
|
|
3777
|
+
children: "Reject"
|
|
3778
|
+
}
|
|
3779
|
+
)
|
|
3780
|
+
] }) : /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: "-" }) }) : null
|
|
3781
|
+
] }, row.id);
|
|
3782
|
+
}) })
|
|
3783
|
+
] }) }),
|
|
3784
|
+
/* @__PURE__ */ jsxs(Group, { justify: "space-between", gap: "xs", children: [
|
|
3785
|
+
/* @__PURE__ */ jsx(Pagination, { size: "sm", total: totalPages, value: page, onChange: setPage, disabled: recordsQuery.isFetching }),
|
|
3786
|
+
isReviewExportStep ? /* @__PURE__ */ jsxs(Group, { gap: "xs", children: [
|
|
3787
|
+
/* @__PURE__ */ jsxs(Text, { size: "xs", c: "dimmed", children: [
|
|
3788
|
+
approvedCompanyIds.length,
|
|
3789
|
+
" approved, ",
|
|
3790
|
+
rejectedCompanyIds.length,
|
|
3791
|
+
" rejected"
|
|
3792
|
+
] }),
|
|
3793
|
+
exportDisabledReason ? /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: exportDisabledReason }) : null,
|
|
3794
|
+
/* @__PURE__ */ jsx(
|
|
3795
|
+
Button,
|
|
3796
|
+
{
|
|
3797
|
+
size: "xs",
|
|
3798
|
+
leftSection: /* @__PURE__ */ jsx(IconPlayerPlay, { size: 14 }),
|
|
3799
|
+
loading: exportExecution.isPending,
|
|
3800
|
+
disabled: !canExport,
|
|
3801
|
+
onClick: () => void exportApproved(),
|
|
3802
|
+
children: isClickUpExportPath ? "Export to ClickUp" : "Export approved"
|
|
3803
|
+
}
|
|
3804
|
+
)
|
|
3805
|
+
] }) : null
|
|
3806
|
+
] }),
|
|
3807
|
+
/* @__PURE__ */ jsx(
|
|
3808
|
+
CustomModal,
|
|
3809
|
+
{
|
|
3810
|
+
opened: Boolean(selectedRecord) && selectedRecordIsLoading,
|
|
3811
|
+
onClose: () => setSelectedRecord(null),
|
|
3812
|
+
size: "xl",
|
|
3813
|
+
children: /* @__PURE__ */ jsx(Center, { p: "xl", children: /* @__PURE__ */ jsx(Loader, { size: "sm" }) })
|
|
3814
|
+
}
|
|
3815
|
+
),
|
|
3816
|
+
/* @__PURE__ */ jsx(
|
|
3817
|
+
CompanyDetailModal,
|
|
3818
|
+
{
|
|
3819
|
+
company: selectedRecord?.entity === "company" ? selectedCompanyQuery.data ?? null : null,
|
|
3820
|
+
onClose: () => setSelectedRecord(null)
|
|
3821
|
+
}
|
|
3822
|
+
),
|
|
3823
|
+
/* @__PURE__ */ jsx(
|
|
3824
|
+
ContactDetailModal,
|
|
3825
|
+
{
|
|
3826
|
+
contact: selectedRecord?.entity === "contact" ? selectedContactQuery.data ?? null : null,
|
|
3827
|
+
onClose: () => setSelectedRecord(null)
|
|
3828
|
+
}
|
|
3829
|
+
)
|
|
3830
|
+
] });
|
|
3831
|
+
}
|
|
3093
3832
|
function BuildTab({
|
|
3094
3833
|
list,
|
|
3095
3834
|
steps,
|
|
3096
3835
|
recommendedStep,
|
|
3097
3836
|
onRunStep,
|
|
3098
3837
|
onRetryStep,
|
|
3099
|
-
onViewRunLog
|
|
3100
|
-
onViewRuns
|
|
3838
|
+
onViewRunLog
|
|
3101
3839
|
}) {
|
|
3102
3840
|
const [selectedStepId, setSelectedStepId] = useState(null);
|
|
3103
3841
|
const [stepInputFormState, setStepInputFormState] = useState({});
|
|
3104
3842
|
const [stepInputError, setStepInputError] = useState(null);
|
|
3105
3843
|
const [stepInputInitialized, setStepInputInitialized] = useState(false);
|
|
3106
3844
|
const [activeRightColumnTab, setActiveRightColumnTab] = useState("configuration");
|
|
3845
|
+
const [credentialSelections, setCredentialSelections] = useState({});
|
|
3846
|
+
const [credentialVerificationById, setCredentialVerificationById] = useState({});
|
|
3847
|
+
const [clickupListId, setClickupListId] = useState("");
|
|
3848
|
+
const [runningResources, setRunningResources] = useState({});
|
|
3107
3849
|
const [stepInputResetKey, setStepInputResetKey] = useState(0);
|
|
3108
3850
|
const currentStep = getDisplayStep(steps, recommendedStep);
|
|
3109
3851
|
const selectedStep = steps.find((step) => step.id === selectedStepId) ?? currentStep;
|
|
@@ -3113,10 +3855,36 @@ function BuildTab({
|
|
|
3113
3855
|
const selectedResourceId = selectedStep?.action?.resourceId ?? null;
|
|
3114
3856
|
const stepSchema = selectedStep?.action?.schema;
|
|
3115
3857
|
const stepLayout = selectedStep?.action?.layout;
|
|
3858
|
+
const credentialRequirements = selectedStep?.credentialRequirements ?? [];
|
|
3859
|
+
const visibleStepLayout = useMemo(
|
|
3860
|
+
() => filterCredentialRequirementFields(stepLayout, credentialRequirements),
|
|
3861
|
+
[stepLayout, credentialRequirements]
|
|
3862
|
+
);
|
|
3863
|
+
const showMainStepConfig = stepSchema && hasMainConfigFields(visibleStepLayout);
|
|
3864
|
+
const showAdvancedStepConfig = stepSchema && hasAdvancedConfigFields(visibleStepLayout);
|
|
3116
3865
|
const recentRunsQuery = useListExecutions(list.id, { resourceId: selectedResourceId, limit: 5 });
|
|
3117
3866
|
const recentRuns = useMemo(() => recentRunsQuery.data ?? [], [recentRunsQuery.data]);
|
|
3867
|
+
const credentialsQuery = useCredentials();
|
|
3868
|
+
const credentials = credentialsQuery.data ?? [];
|
|
3869
|
+
const verifyCredential = useVerifyCredential();
|
|
3118
3870
|
const canRunSelectedAction = !!selectedStep?.action && (selectedActionKind === "retry_failed" || selectedActionKind === "run_next_batch");
|
|
3871
|
+
const selectedResourceIsRunning = selectedResourceId ? runningResources[selectedResourceId] ?? false : false;
|
|
3872
|
+
const selectedActionDisabled = !canRunSelectedAction || selectedResourceIsRunning;
|
|
3873
|
+
const selectedActionLabel = selectedResourceIsRunning ? "Running..." : selectedActionKind === "none" ? "No action" : getStepActionLabel(selectedActionKind);
|
|
3119
3874
|
const selectedActionIcon = selectedActionKind === "retry_failed" ? /* @__PURE__ */ jsx(IconRefresh, { size: 14 }) : /* @__PURE__ */ jsx(IconPlayerPlay, { size: 14 });
|
|
3875
|
+
const handleResourceRunningChange = useCallback((resourceId, isRunning) => {
|
|
3876
|
+
setRunningResources((current) => {
|
|
3877
|
+
if (current[resourceId] === isRunning) return current;
|
|
3878
|
+
return { ...current, [resourceId]: isRunning };
|
|
3879
|
+
});
|
|
3880
|
+
}, []);
|
|
3881
|
+
const handleSelectedResourceRunningChange = useCallback(
|
|
3882
|
+
(isRunning) => {
|
|
3883
|
+
if (!selectedResourceId) return;
|
|
3884
|
+
handleResourceRunningChange(selectedResourceId, isRunning);
|
|
3885
|
+
},
|
|
3886
|
+
[handleResourceRunningChange, selectedResourceId]
|
|
3887
|
+
);
|
|
3120
3888
|
useEffect(() => {
|
|
3121
3889
|
setStepInputFormState(getInitialStepInput(list, selectedStep?.action));
|
|
3122
3890
|
setStepInputError(null);
|
|
@@ -3139,8 +3907,45 @@ function BuildTab({
|
|
|
3139
3907
|
setStepInputFormState(next);
|
|
3140
3908
|
if (stepInputError) setStepInputError(null);
|
|
3141
3909
|
};
|
|
3910
|
+
const handleCredentialSelect = (requirement, credential) => {
|
|
3911
|
+
setCredentialSelections((current) => ({
|
|
3912
|
+
...current,
|
|
3913
|
+
[requirement.key]: credential?.id ?? null
|
|
3914
|
+
}));
|
|
3915
|
+
setStepInputFormState((current) => setValueAtInputPath(current, requirement.inputPath, credential?.name ?? ""));
|
|
3916
|
+
if (stepInputError) setStepInputError(null);
|
|
3917
|
+
};
|
|
3918
|
+
const handleVerifyCredential = (credential) => {
|
|
3919
|
+
verifyCredential.mutate(credential.id, {
|
|
3920
|
+
onSuccess: (result) => {
|
|
3921
|
+
setCredentialVerificationById((current) => ({
|
|
3922
|
+
...current,
|
|
3923
|
+
[credential.id]: {
|
|
3924
|
+
status: result.ok ? "success" : "error",
|
|
3925
|
+
checkedAt: result.checkedAt,
|
|
3926
|
+
message: result.message ?? (result.ok ? "Credential verified." : "Credential verification failed."),
|
|
3927
|
+
details: result.details
|
|
3928
|
+
}
|
|
3929
|
+
}));
|
|
3930
|
+
},
|
|
3931
|
+
onError: (error) => {
|
|
3932
|
+
setCredentialVerificationById((current) => ({
|
|
3933
|
+
...current,
|
|
3934
|
+
[credential.id]: {
|
|
3935
|
+
status: "error",
|
|
3936
|
+
message: error instanceof Error ? error.message : "Credential verification failed."
|
|
3937
|
+
}
|
|
3938
|
+
}));
|
|
3939
|
+
}
|
|
3940
|
+
});
|
|
3941
|
+
};
|
|
3942
|
+
const handleClickupListIdChange = (value) => {
|
|
3943
|
+
setClickupListId(value);
|
|
3944
|
+
setStepInputFormState((current) => setValueAtInputPath(current, "clickupListId", value));
|
|
3945
|
+
if (stepInputError) setStepInputError(null);
|
|
3946
|
+
};
|
|
3142
3947
|
const handleSelectedAction = () => {
|
|
3143
|
-
if (!selectedStep ||
|
|
3948
|
+
if (!selectedStep || selectedActionDisabled) return;
|
|
3144
3949
|
if (stepSchema) {
|
|
3145
3950
|
const parsed = stepSchema.safeParse(stepInputFormState);
|
|
3146
3951
|
if (!parsed.success) {
|
|
@@ -3167,196 +3972,238 @@ function BuildTab({
|
|
|
3167
3972
|
if (!resourceId) return;
|
|
3168
3973
|
onViewRunLog(resourceId, run.executionId);
|
|
3169
3974
|
};
|
|
3170
|
-
return /* @__PURE__ */ jsx(
|
|
3171
|
-
|
|
3172
|
-
|
|
3173
|
-
|
|
3174
|
-
|
|
3175
|
-
|
|
3176
|
-
|
|
3177
|
-
|
|
3178
|
-
|
|
3179
|
-
|
|
3180
|
-
|
|
3181
|
-
|
|
3182
|
-
|
|
3183
|
-
|
|
3184
|
-
|
|
3185
|
-
|
|
3186
|
-
|
|
3187
|
-
|
|
3188
|
-
|
|
3189
|
-
|
|
3190
|
-
|
|
3191
|
-
|
|
3192
|
-
|
|
3193
|
-
|
|
3194
|
-
|
|
3195
|
-
|
|
3196
|
-
|
|
3197
|
-
|
|
3198
|
-
|
|
3199
|
-
|
|
3200
|
-
|
|
3201
|
-
|
|
3202
|
-
|
|
3203
|
-
|
|
3204
|
-
style: {
|
|
3205
|
-
alignItems: "center",
|
|
3206
|
-
...getBuildToneStyle(stepTone),
|
|
3207
|
-
borderRadius: 999,
|
|
3208
|
-
borderStyle: "solid",
|
|
3209
|
-
borderWidth: 1,
|
|
3210
|
-
display: "flex",
|
|
3211
|
-
flexShrink: 0,
|
|
3212
|
-
fontWeight: 700,
|
|
3213
|
-
justifyContent: "center"
|
|
3214
|
-
},
|
|
3215
|
-
children: index + 1
|
|
3216
|
-
}
|
|
3217
|
-
),
|
|
3218
|
-
/* @__PURE__ */ jsxs(Stack, { gap: 4, style: { minWidth: 0, flex: 1 }, children: [
|
|
3219
|
-
/* @__PURE__ */ jsxs(Group, { gap: "xs", justify: "space-between", wrap: "nowrap", children: [
|
|
3220
|
-
/* @__PURE__ */ jsx(Text, { fw: 700, c: isPassiveWaiting ? "dimmed" : void 0, truncate: true, children: step.label }),
|
|
3221
|
-
isCurrent ? /* @__PURE__ */ jsx(StatusPill, { label: "Current", tone: step.status }) : null,
|
|
3222
|
-
!isCurrent && isWaiting ? /* @__PURE__ */ jsx(StatusPill, { label: "Waiting", tone: "blocked" }) : null
|
|
3223
|
-
] }),
|
|
3224
|
-
/* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", lineClamp: 2, children: step.description }),
|
|
3225
|
-
/* @__PURE__ */ jsx(StepCounterLine, { step })
|
|
3226
|
-
] })
|
|
3227
|
-
] })
|
|
3975
|
+
return /* @__PURE__ */ jsx(TabSection, { icon: /* @__PURE__ */ jsx(IconBolt, { size: 16 }), title: "Build", description: getBuildTabDescription(steps, currentStep), children: /* @__PURE__ */ jsxs(SimpleGrid, { cols: { base: 1, md: 2 }, spacing: "md", children: [
|
|
3976
|
+
/* @__PURE__ */ jsx(Card, { withBorder: true, style: { height: "100%", display: "flex", flexDirection: "column" }, children: /* @__PURE__ */ jsxs(Stack, { gap: "xs", style: { flex: 1, minHeight: 0 }, children: [
|
|
3977
|
+
steps.map(
|
|
3978
|
+
(step) => step.action?.resourceId ? /* @__PURE__ */ jsx(
|
|
3979
|
+
BuildStepRunningWatcher,
|
|
3980
|
+
{
|
|
3981
|
+
resourceId: step.action.resourceId,
|
|
3982
|
+
onRunningChange: handleResourceRunningChange
|
|
3983
|
+
},
|
|
3984
|
+
`running-${step.id}`
|
|
3985
|
+
) : null
|
|
3986
|
+
),
|
|
3987
|
+
steps.map((step, index) => {
|
|
3988
|
+
const isCurrent = currentStep?.id === step.id;
|
|
3989
|
+
const isSelected = selectedStep?.id === step.id;
|
|
3990
|
+
const stepResourceId = step.action?.resourceId ?? null;
|
|
3991
|
+
const isStepRunning = stepResourceId ? runningResources[stepResourceId] ?? false : false;
|
|
3992
|
+
const isWaiting = step.status === "blocked";
|
|
3993
|
+
const isPassiveWaiting = isWaiting && !isSelected && !isCurrent;
|
|
3994
|
+
const stepTone = isStepRunning ? "ready" : isSelected || isCurrent ? step.status : step.status === "complete" || isWaiting ? step.status : "neutral";
|
|
3995
|
+
return /* @__PURE__ */ jsx(
|
|
3996
|
+
UnstyledButton,
|
|
3997
|
+
{
|
|
3998
|
+
onClick: () => setSelectedStepId(step.id),
|
|
3999
|
+
style: {
|
|
4000
|
+
backgroundColor: isSelected ? "var(--surface-primary-strong)" : isStepRunning ? "color-mix(in srgb, var(--color-primary) 12%, transparent)" : isPassiveWaiting ? "color-mix(in srgb, var(--color-surface-hover) 38%, transparent)" : "transparent",
|
|
4001
|
+
border: isSelected ? "var(--active-border)" : isStepRunning ? "1px solid var(--border-primary-muted)" : "1px solid var(--color-border)",
|
|
4002
|
+
borderStyle: isPassiveWaiting && !isStepRunning ? "dashed" : "solid",
|
|
4003
|
+
borderRadius: 8,
|
|
4004
|
+
display: "block",
|
|
4005
|
+
opacity: isPassiveWaiting && !isStepRunning ? 0.72 : 1,
|
|
4006
|
+
padding: 12,
|
|
4007
|
+
textAlign: "left",
|
|
4008
|
+
width: "100%"
|
|
3228
4009
|
},
|
|
3229
|
-
|
|
3230
|
-
|
|
3231
|
-
|
|
3232
|
-
|
|
3233
|
-
|
|
3234
|
-
|
|
3235
|
-
|
|
3236
|
-
|
|
3237
|
-
|
|
3238
|
-
|
|
3239
|
-
|
|
4010
|
+
children: /* @__PURE__ */ jsxs(Group, { gap: "sm", align: "flex-start", wrap: "nowrap", children: [
|
|
4011
|
+
/* @__PURE__ */ jsx(
|
|
4012
|
+
Box,
|
|
4013
|
+
{
|
|
4014
|
+
w: 28,
|
|
4015
|
+
h: 28,
|
|
4016
|
+
style: {
|
|
4017
|
+
alignItems: "center",
|
|
4018
|
+
...getBuildToneStyle(stepTone),
|
|
4019
|
+
borderRadius: 999,
|
|
4020
|
+
borderStyle: "solid",
|
|
4021
|
+
borderWidth: 1,
|
|
4022
|
+
display: "flex",
|
|
4023
|
+
flexShrink: 0,
|
|
4024
|
+
fontWeight: 700,
|
|
4025
|
+
justifyContent: "center"
|
|
4026
|
+
},
|
|
4027
|
+
children: index + 1
|
|
4028
|
+
}
|
|
4029
|
+
),
|
|
4030
|
+
/* @__PURE__ */ jsxs(Stack, { gap: 4, style: { minWidth: 0, flex: 1 }, children: [
|
|
4031
|
+
/* @__PURE__ */ jsxs(Group, { gap: "xs", justify: "space-between", wrap: "nowrap", children: [
|
|
4032
|
+
/* @__PURE__ */ jsx(Text, { fw: 700, c: isPassiveWaiting && !isStepRunning ? "dimmed" : void 0, truncate: true, children: step.label }),
|
|
4033
|
+
isStepRunning ? /* @__PURE__ */ jsx(StatusPill, { label: "Running", tone: "ready" }) : null,
|
|
4034
|
+
!isStepRunning && isCurrent ? /* @__PURE__ */ jsx(StatusPill, { label: "Current", tone: step.status }) : null,
|
|
4035
|
+
!isStepRunning && !isCurrent && isWaiting ? /* @__PURE__ */ jsx(StatusPill, { label: "Waiting", tone: "blocked" }) : null
|
|
4036
|
+
] }),
|
|
4037
|
+
/* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", lineClamp: 2, children: step.description }),
|
|
4038
|
+
/* @__PURE__ */ jsx(StepCounterLine, { step })
|
|
4039
|
+
] })
|
|
4040
|
+
] })
|
|
4041
|
+
},
|
|
4042
|
+
step.id
|
|
4043
|
+
);
|
|
4044
|
+
})
|
|
4045
|
+
] }) }),
|
|
4046
|
+
selectedStep ? /* @__PURE__ */ jsx(Card, { withBorder: true, style: { height: "100%", display: "flex", flexDirection: "column" }, children: /* @__PURE__ */ jsxs(Stack, { gap: "md", style: { flex: 1, minHeight: 0 }, children: [
|
|
4047
|
+
/* @__PURE__ */ jsxs(Stack, { gap: 2, style: { minWidth: 0, flexShrink: 0 }, children: [
|
|
4048
|
+
/* @__PURE__ */ jsxs(Text, { size: "xs", c: "dimmed", fw: 700, tt: "uppercase", children: [
|
|
4049
|
+
"Step ",
|
|
4050
|
+
selectedStepIndex + 1,
|
|
4051
|
+
" details"
|
|
4052
|
+
] }),
|
|
4053
|
+
/* @__PURE__ */ jsx(Title, { order: 5, children: selectedStep.label })
|
|
4054
|
+
] }),
|
|
4055
|
+
/* @__PURE__ */ jsx(BuildStepProgressBar, { step: selectedStep }),
|
|
4056
|
+
/* @__PURE__ */ jsx(
|
|
4057
|
+
StepDetailRightColumn,
|
|
4058
|
+
{
|
|
4059
|
+
activeTab: activeRightColumnTab,
|
|
4060
|
+
onTabChange: setActiveRightColumnTab,
|
|
4061
|
+
configuration: /* @__PURE__ */ jsxs(Stack, { gap: "sm", children: [
|
|
4062
|
+
selectedResourceId && selectedStep.stageKey ? /* @__PURE__ */ jsx(
|
|
4063
|
+
LeadGenLiveStatusPanel,
|
|
4064
|
+
{
|
|
4065
|
+
listId: list.id,
|
|
4066
|
+
resourceId: selectedResourceId,
|
|
4067
|
+
stageKey: selectedStep.stageKey,
|
|
4068
|
+
stepLabel: selectedStep.label,
|
|
4069
|
+
enabled: true,
|
|
4070
|
+
onRunningChange: handleSelectedResourceRunningChange
|
|
4071
|
+
},
|
|
4072
|
+
selectedResourceId
|
|
4073
|
+
) : null,
|
|
4074
|
+
selectedStep.status === "blocked" ? /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: selectedStep.emptyBlockedText }) : null,
|
|
4075
|
+
selectedStep.outputs.includes(selectedStep.primaryEntity) && selectedStep.ready === 0 && selectedStep.complete === 0 && selectedStep.failed === 0 && selectedStep.blocked === 0 ? /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: "Run this step to populate members." }) : null,
|
|
4076
|
+
!selectedStep.outputs.includes(selectedStep.primaryEntity) && selectedStep.recommendedAction?.defaultSize !== void 0 && selectedStep.recommendedAction.maxSize !== void 0 ? /* @__PURE__ */ jsxs(Text, { size: "xs", c: "dimmed", children: [
|
|
4077
|
+
"Batch size: ",
|
|
4078
|
+
selectedStep.recommendedAction.defaultSize,
|
|
4079
|
+
" default,",
|
|
4080
|
+
" ",
|
|
4081
|
+
selectedStep.recommendedAction.maxSize,
|
|
4082
|
+
" max."
|
|
4083
|
+
] }) : null,
|
|
4084
|
+
showMainStepConfig && visibleStepLayout ? /* @__PURE__ */ jsx(
|
|
4085
|
+
StepConfigForm,
|
|
4086
|
+
{
|
|
4087
|
+
slot: "main",
|
|
4088
|
+
schema: stepSchema,
|
|
4089
|
+
layout: visibleStepLayout,
|
|
4090
|
+
value: stepInputFormState,
|
|
4091
|
+
onChange: (v) => handleStepInputChange(asRecord3(v) ?? {}),
|
|
4092
|
+
disabled: !canRunSelectedAction
|
|
4093
|
+
},
|
|
4094
|
+
`${selectedResourceId ?? "none"}-main-${stepInputResetKey}`
|
|
4095
|
+
) : !credentialRequirements.length ? /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: "No configuration for this step." }) : null,
|
|
4096
|
+
/* @__PURE__ */ jsx(
|
|
4097
|
+
CredentialRequirementsPanel,
|
|
4098
|
+
{
|
|
4099
|
+
requirements: credentialRequirements,
|
|
4100
|
+
credentials,
|
|
4101
|
+
credentialsLoading: credentialsQuery.isLoading,
|
|
4102
|
+
selections: credentialSelections,
|
|
4103
|
+
verificationByCredentialId: credentialVerificationById,
|
|
4104
|
+
verifyingCredentialId: verifyCredential.isPending ? verifyCredential.variables ?? null : null,
|
|
4105
|
+
onSelect: handleCredentialSelect,
|
|
4106
|
+
onVerify: handleVerifyCredential
|
|
4107
|
+
}
|
|
4108
|
+
),
|
|
4109
|
+
selectedStep.capabilityKey === "lead-gen.export.list" || getClickUpRequirement(selectedStep) ? /* @__PURE__ */ jsx(
|
|
4110
|
+
TextInput,
|
|
4111
|
+
{
|
|
4112
|
+
label: "ClickUp List ID",
|
|
4113
|
+
description: "Destination List ID for approved company tasks.",
|
|
4114
|
+
placeholder: "123456789",
|
|
4115
|
+
value: clickupListId,
|
|
4116
|
+
onChange: (event) => handleClickupListIdChange(event.currentTarget.value)
|
|
4117
|
+
}
|
|
4118
|
+
) : null
|
|
3240
4119
|
] }),
|
|
3241
|
-
/* @__PURE__ */ jsx(
|
|
3242
|
-
|
|
3243
|
-
StepDetailRightColumn,
|
|
4120
|
+
advanced: showAdvancedStepConfig && visibleStepLayout ? /* @__PURE__ */ jsx(
|
|
4121
|
+
StepConfigForm,
|
|
3244
4122
|
{
|
|
3245
|
-
|
|
3246
|
-
|
|
3247
|
-
|
|
3248
|
-
|
|
3249
|
-
|
|
3250
|
-
|
|
3251
|
-
|
|
3252
|
-
|
|
3253
|
-
|
|
3254
|
-
|
|
3255
|
-
|
|
3256
|
-
|
|
3257
|
-
|
|
3258
|
-
|
|
3259
|
-
|
|
3260
|
-
|
|
3261
|
-
|
|
3262
|
-
|
|
3263
|
-
|
|
3264
|
-
|
|
3265
|
-
|
|
3266
|
-
|
|
3267
|
-
|
|
3268
|
-
|
|
3269
|
-
|
|
3270
|
-
|
|
3271
|
-
|
|
3272
|
-
|
|
4123
|
+
slot: "advanced",
|
|
4124
|
+
schema: stepSchema,
|
|
4125
|
+
layout: visibleStepLayout,
|
|
4126
|
+
value: stepInputFormState,
|
|
4127
|
+
onChange: (v) => handleStepInputChange(asRecord3(v) ?? {}),
|
|
4128
|
+
disabled: !canRunSelectedAction
|
|
4129
|
+
},
|
|
4130
|
+
`${selectedResourceId ?? "none"}-advanced-${stepInputResetKey}`
|
|
4131
|
+
) : void 0,
|
|
4132
|
+
records: /* @__PURE__ */ jsx(
|
|
4133
|
+
StepRecordsPanel,
|
|
4134
|
+
{
|
|
4135
|
+
list,
|
|
4136
|
+
step: selectedStep,
|
|
4137
|
+
credentialSelections,
|
|
4138
|
+
credentials,
|
|
4139
|
+
clickupListId
|
|
4140
|
+
},
|
|
4141
|
+
selectedStep.id
|
|
4142
|
+
),
|
|
4143
|
+
runs: selectedResourceId ? /* @__PURE__ */ jsxs(Stack, { gap: "xs", children: [
|
|
4144
|
+
/* @__PURE__ */ jsxs(Group, { justify: "space-between", gap: "xs", children: [
|
|
4145
|
+
/* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", fw: 700, tt: "uppercase", children: "Recent runs" }),
|
|
4146
|
+
recentRunsQuery.isFetching ? /* @__PURE__ */ jsx(Loader, { size: "xs" }) : null
|
|
4147
|
+
] }),
|
|
4148
|
+
!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) => {
|
|
4149
|
+
const canUseSettings = hasRunInput(run);
|
|
4150
|
+
return /* @__PURE__ */ jsx(
|
|
4151
|
+
Box,
|
|
3273
4152
|
{
|
|
3274
|
-
|
|
3275
|
-
|
|
3276
|
-
|
|
3277
|
-
|
|
3278
|
-
|
|
3279
|
-
|
|
4153
|
+
style: {
|
|
4154
|
+
border: "1px solid var(--color-border)",
|
|
4155
|
+
borderRadius: 8,
|
|
4156
|
+
padding: "8px 10px",
|
|
4157
|
+
width: "100%"
|
|
4158
|
+
},
|
|
4159
|
+
children: /* @__PURE__ */ jsxs(Group, { justify: "space-between", gap: "xs", wrap: "nowrap", children: [
|
|
4160
|
+
/* @__PURE__ */ jsx(
|
|
4161
|
+
UnstyledButton,
|
|
4162
|
+
{
|
|
4163
|
+
onClick: () => openRecentRunLog(run),
|
|
4164
|
+
style: { flex: 1, minWidth: 0, textAlign: "left" },
|
|
4165
|
+
children: /* @__PURE__ */ jsxs(Group, { justify: "space-between", gap: "xs", wrap: "nowrap", children: [
|
|
4166
|
+
/* @__PURE__ */ jsxs(Stack, { gap: 2, style: { minWidth: 0 }, children: [
|
|
4167
|
+
/* @__PURE__ */ jsx(Text, { size: "sm", fw: 600, truncate: true, children: formatDateTime4(run.createdAt) }),
|
|
4168
|
+
/* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", ff: "monospace", truncate: true, children: run.executionId })
|
|
4169
|
+
] }),
|
|
4170
|
+
/* @__PURE__ */ jsx(Badge, { size: "sm", variant: "light", color: getRunStatusColor(run.status), children: run.status })
|
|
4171
|
+
] })
|
|
4172
|
+
}
|
|
4173
|
+
),
|
|
4174
|
+
/* @__PURE__ */ jsx(Tooltip, { label: "Use this run's settings", children: /* @__PURE__ */ jsx(
|
|
4175
|
+
Button,
|
|
4176
|
+
{
|
|
4177
|
+
size: "xs",
|
|
4178
|
+
variant: "subtle",
|
|
4179
|
+
leftSection: /* @__PURE__ */ jsx(IconSettings, { size: 12 }),
|
|
4180
|
+
disabled: !canUseSettings,
|
|
4181
|
+
onClick: () => loadRecentRunInput(run),
|
|
4182
|
+
children: "Use settings"
|
|
4183
|
+
}
|
|
4184
|
+
) })
|
|
4185
|
+
] })
|
|
3280
4186
|
},
|
|
3281
|
-
|
|
3282
|
-
)
|
|
3283
|
-
|
|
3284
|
-
|
|
3285
|
-
|
|
3286
|
-
|
|
3287
|
-
|
|
3288
|
-
|
|
3289
|
-
|
|
3290
|
-
|
|
3291
|
-
|
|
3292
|
-
|
|
3293
|
-
|
|
3294
|
-
|
|
3295
|
-
|
|
3296
|
-
|
|
3297
|
-
|
|
3298
|
-
|
|
3299
|
-
|
|
3300
|
-
|
|
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
|
-
] })
|
|
3326
|
-
},
|
|
3327
|
-
run.executionId
|
|
3328
|
-
);
|
|
3329
|
-
}) })
|
|
3330
|
-
] }) : /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: "No runs available for this step." }),
|
|
3331
|
-
action: /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
3332
|
-
stepInputError ? /* @__PURE__ */ jsx(Alert, { color: "red", icon: /* @__PURE__ */ jsx(IconAlertCircle, { size: 16 }), variant: "light", children: stepInputError }) : null,
|
|
3333
|
-
/* @__PURE__ */ jsxs(Group, { gap: "xs", justify: "flex-end", wrap: "nowrap", children: [
|
|
3334
|
-
/* @__PURE__ */ jsx(
|
|
3335
|
-
Button,
|
|
3336
|
-
{
|
|
3337
|
-
leftSection: selectedActionIcon,
|
|
3338
|
-
disabled: !canRunSelectedAction,
|
|
3339
|
-
onClick: handleSelectedAction,
|
|
3340
|
-
children: selectedActionKind === "none" ? "No action" : getStepActionLabel(selectedActionKind)
|
|
3341
|
-
}
|
|
3342
|
-
),
|
|
3343
|
-
recentRuns.length > 0 ? /* @__PURE__ */ jsx(
|
|
3344
|
-
Button,
|
|
3345
|
-
{
|
|
3346
|
-
variant: "light",
|
|
3347
|
-
leftSection: /* @__PURE__ */ jsx(IconPlayerPlay, { size: 14 }),
|
|
3348
|
-
onClick: () => onViewRuns(selectedResourceId),
|
|
3349
|
-
children: "View runs"
|
|
3350
|
-
}
|
|
3351
|
-
) : null
|
|
3352
|
-
] })
|
|
3353
|
-
] })
|
|
3354
|
-
}
|
|
3355
|
-
)
|
|
3356
|
-
] }) }) : null
|
|
3357
|
-
] })
|
|
3358
|
-
}
|
|
3359
|
-
);
|
|
4187
|
+
run.executionId
|
|
4188
|
+
);
|
|
4189
|
+
}) })
|
|
4190
|
+
] }) : /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: "No runs available for this step." }),
|
|
4191
|
+
action: /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
4192
|
+
stepInputError ? /* @__PURE__ */ jsx(Alert, { color: "red", icon: /* @__PURE__ */ jsx(IconAlertCircle, { size: 16 }), variant: "light", children: stepInputError }) : null,
|
|
4193
|
+
/* @__PURE__ */ jsx(Group, { gap: "xs", justify: "flex-end", wrap: "nowrap", children: /* @__PURE__ */ jsx(
|
|
4194
|
+
Button,
|
|
4195
|
+
{
|
|
4196
|
+
leftSection: selectedActionIcon,
|
|
4197
|
+
disabled: selectedActionDisabled,
|
|
4198
|
+
onClick: handleSelectedAction,
|
|
4199
|
+
children: selectedActionLabel
|
|
4200
|
+
}
|
|
4201
|
+
) })
|
|
4202
|
+
] })
|
|
4203
|
+
}
|
|
4204
|
+
)
|
|
4205
|
+
] }) }) : null
|
|
4206
|
+
] }) });
|
|
3360
4207
|
}
|
|
3361
4208
|
function MembersTab({
|
|
3362
4209
|
listId,
|
|
@@ -3638,10 +4485,6 @@ function LeadGenListDetailPage({ listId }) {
|
|
|
3638
4485
|
params: { workflowId: resourceId },
|
|
3639
4486
|
search: { exec: executionId }
|
|
3640
4487
|
});
|
|
3641
|
-
},
|
|
3642
|
-
onViewRuns: (resourceId) => {
|
|
3643
|
-
setRunsResourceFilter(resourceId);
|
|
3644
|
-
setActiveTab("runs");
|
|
3645
4488
|
}
|
|
3646
4489
|
}
|
|
3647
4490
|
) }),
|