@elevasis/ui 2.25.4 → 2.25.6

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.
Files changed (68) hide show
  1. package/dist/app/index.css +2 -6
  2. package/dist/app/index.d.ts +63 -56
  3. package/dist/app/index.js +3 -2
  4. package/dist/charts/index.js +1 -1
  5. package/dist/chunk-5RLYII6P.js +314 -0
  6. package/dist/chunk-6U7AIIHF.js +880 -0
  7. package/dist/{chunk-5O5VC4HB.js → chunk-7F3IQMLI.js} +1 -1
  8. package/dist/{chunk-ZBRRVDYJ.js → chunk-ARJPZ66V.js} +42 -760
  9. package/dist/{chunk-IS53MXE4.js → chunk-BDKM56TP.js} +1 -1
  10. package/dist/{chunk-FVXM2MN6.js → chunk-C7IBFI5B.js} +1 -1
  11. package/dist/{chunk-DUUH3CHC.js → chunk-CPAJXBTL.js} +10 -6
  12. package/dist/{chunk-3FBCFSDF.js → chunk-ECNNI3NT.js} +2 -1
  13. package/dist/chunk-HAEJ4M54.js +94 -0
  14. package/dist/{chunk-7RPH2VXV.js → chunk-JXSBOG2R.js} +1 -1
  15. package/dist/{chunk-E7WTCAVX.js → chunk-KNISO652.js} +2 -2
  16. package/dist/{chunk-5PLAJ6IS.js → chunk-L7D6KNHV.js} +457 -335
  17. package/dist/{chunk-JMI7L7Y7.js → chunk-LPM7O6XM.js} +2 -233
  18. package/dist/{chunk-2XWXFT2Z.js → chunk-QARSVM7Q.js} +1 -1
  19. package/dist/{chunk-FYT6LYJP.js → chunk-SBQ4MYQV.js} +3 -2
  20. package/dist/{chunk-MU4VPAMR.js → chunk-YRKQNPK2.js} +1 -1
  21. package/dist/components/index.css +2 -6
  22. package/dist/components/index.d.ts +11 -2
  23. package/dist/components/index.js +25 -23
  24. package/dist/components/navigation/index.css +2 -6
  25. package/dist/features/auth/index.css +2 -6
  26. package/dist/features/crm/index.css +2 -6
  27. package/dist/features/crm/index.js +9 -8
  28. package/dist/features/dashboard/index.css +2 -6
  29. package/dist/features/dashboard/index.js +9 -8
  30. package/dist/features/delivery/index.css +2 -6
  31. package/dist/features/delivery/index.js +10 -9
  32. package/dist/features/knowledge/index.d.ts +33 -0
  33. package/dist/features/knowledge/index.js +406 -0
  34. package/dist/features/lead-gen/index.css +2 -6
  35. package/dist/features/lead-gen/index.d.ts +158 -151
  36. package/dist/features/lead-gen/index.js +10 -9
  37. package/dist/features/monitoring/index.css +2 -6
  38. package/dist/features/monitoring/index.js +10 -9
  39. package/dist/features/monitoring/requests/index.css +2 -6
  40. package/dist/features/monitoring/requests/index.js +8 -7
  41. package/dist/features/operations/index.css +2 -6
  42. package/dist/features/operations/index.js +15 -13
  43. package/dist/features/settings/index.css +2 -6
  44. package/dist/features/settings/index.js +9 -8
  45. package/dist/hooks/delivery/index.css +2 -6
  46. package/dist/hooks/index.css +2 -6
  47. package/dist/hooks/index.d.ts +14 -3
  48. package/dist/hooks/index.js +8 -7
  49. package/dist/hooks/published.css +2 -6
  50. package/dist/hooks/published.d.ts +14 -3
  51. package/dist/hooks/published.js +8 -7
  52. package/dist/index.css +2 -6
  53. package/dist/index.d.ts +611 -593
  54. package/dist/index.js +8 -7
  55. package/dist/knowledge/index.d.ts +643 -0
  56. package/dist/knowledge/index.js +496 -0
  57. package/dist/organization/index.css +2 -6
  58. package/dist/provider/index.css +2 -6
  59. package/dist/provider/index.d.ts +346 -339
  60. package/dist/provider/index.js +6 -5
  61. package/dist/provider/published.css +2 -6
  62. package/dist/provider/published.d.ts +346 -339
  63. package/dist/provider/published.js +5 -4
  64. package/dist/vite-plugin-knowledge/index.d.ts +37 -0
  65. package/dist/vite-plugin-knowledge/index.js +67 -0
  66. package/package.json +45 -33
  67. package/src/knowledge/README.md +31 -0
  68. package/dist/{chunk-U2KJXTTV.js → chunk-TAIX4NO3.js} +1 -1
@@ -1,19 +1,20 @@
1
- import { DEFAULT_ORGANIZATION_MODEL_PROSPECTING } from './chunk-IS53MXE4.js';
1
+ import { DEFAULT_ORGANIZATION_MODEL_PROSPECTING } from './chunk-BDKM56TP.js';
2
2
  import { PageContainer } from './chunk-BZZCNLT6.js';
3
3
  import { TableSelectionToolbar, SortableHeader } from './chunk-TUMSNGTX.js';
4
4
  import { SubshellNavItem } from './chunk-X4WBGKJQ.js';
5
5
  import { SubshellSidebarSection } from './chunk-IIMU5YAJ.js';
6
6
  import { FilterBar } from './chunk-PDHTXPSF.js';
7
7
  import { CustomModal } from './chunk-KVJ3LFH2.js';
8
- import { acquisitionListKeys, useListsTelemetry, useLists, useCreateList, useTableSort, sortData, usePaginationState, useTableSelection, useWorkflowExecution, useList, useListProgress, useListExecutions, useDeleteList, useUpdateList, useCompanyFacets, useCompanies, useDeleteCompanies, useContacts, useDeleteContacts, useListMembers, useListMember, useTransitionListMember, useDeriveActions, useArtifacts } from './chunk-DUUH3CHC.js';
8
+ import { acquisitionListKeys, useListsTelemetry, useLists, useCreateList, useTableSort, sortData, usePaginationState, useTableSelection, useWorkflowExecution, useList, useListProgress, useListExecutions, useDeleteList, useUpdateList, useUpdateListConfig, useCompanyFacets, useCompanies, useDeleteCompanies, useContacts, useDeleteContacts, useListMembers, useListMember, useTransitionListMember, useDeriveActions, useArtifacts } from './chunk-CPAJXBTL.js';
9
9
  import { showApiErrorNotification, showSuccessNotification } from './chunk-HKBEURCV.js';
10
- import { useListActions, LEAD_GEN_STAGE_CATALOG, LEAD_GEN_PIPELINE_DEFINITIONS, findPipeline } from './chunk-JMI7L7Y7.js';
11
10
  import { SubshellContentContainer } from './chunk-TKAYX2SP.js';
12
11
  import { PageTitleCaption, CenteredErrorState, StatCard, CardHeader, EmptyState, JsonViewer } from './chunk-U36X6NZM.js';
12
+ import { useListActions } from './chunk-LPM7O6XM.js';
13
+ import { LEAD_GEN_STAGE_CATALOG, LEAD_GEN_PIPELINE_DEFINITIONS, findPipeline } from './chunk-5RLYII6P.js';
13
14
  import { useRouterContext } from './chunk-Q7DJKLEN.js';
14
15
  import { useElevasisServices } from './chunk-5WWZXCS5.js';
15
- import { Stack, Paper, Text, Anchor, Group, Title, ActionIcon, Divider, Box, SimpleGrid, Badge, Card, Center, Loader, Alert, Table, Button, TextInput, Select, Checkbox, Pagination, Textarea, NumberInput, Switch, Tooltip, Tabs, ThemeIcon, Collapse, SegmentedControl, UnstyledButton, Drawer, ScrollArea } from '@mantine/core';
16
- import { IconLayoutGrid, IconList, IconBuilding, IconAddressBook, IconTarget, IconExternalLink, IconX, IconAlertCircle, IconPlayerPlay, IconArrowRight, IconSparkles, IconListDetails, IconPlus, IconSearch, IconAlertTriangle, IconLayoutDashboard, IconBolt, IconCopy, IconUsers, IconSwitchHorizontal, IconTrash, IconBuildingFactory2, IconArrowLeft, IconRefresh, IconChevronDown, IconChevronRight, IconMail, IconUser, IconDatabase } from '@tabler/icons-react';
16
+ import { Stack, Group, Title, Text, Paper, Anchor, ActionIcon, Divider, Box, SimpleGrid, Badge, Card, Center, Loader, Alert, Table, Button, TextInput, Select, Checkbox, Pagination, Textarea, NumberInput, Switch, Tooltip, Tabs, ThemeIcon, Collapse, SegmentedControl, UnstyledButton, Drawer, 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, IconSwitchHorizontal, IconTrash, IconBuildingFactory2, IconArrowLeft, IconChevronDown, IconChevronRight, IconRefresh, IconMail, IconUser, IconDatabase } from '@tabler/icons-react';
17
18
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
18
19
  import { Link, useNavigate, useSearch } from '@tanstack/react-router';
19
20
  import { useQueryClient, useMutation } from '@tanstack/react-query';
@@ -93,6 +94,22 @@ function createBuildPlanSnapshotFromTemplateId(templateId) {
93
94
  })
94
95
  };
95
96
  }
97
+ function TabSection({ icon, title, description, rightSection, children }) {
98
+ const wrappedIcon = icon ? /* @__PURE__ */ jsx(ThemeIcon, { size: "md", variant: "light", children: icon }) : null;
99
+ return /* @__PURE__ */ jsxs(Stack, { gap: "sm", p: "md", children: [
100
+ /* @__PURE__ */ jsxs(Group, { justify: "space-between", gap: "md", align: "flex-start", wrap: "nowrap", children: [
101
+ /* @__PURE__ */ jsxs(Stack, { gap: 2, style: { minWidth: 0 }, children: [
102
+ /* @__PURE__ */ jsxs(Group, { gap: "xs", wrap: "nowrap", children: [
103
+ wrappedIcon,
104
+ /* @__PURE__ */ jsx(Title, { order: 3, style: { overflowWrap: "anywhere" }, children: title })
105
+ ] }),
106
+ description ? /* @__PURE__ */ jsx(Text, { size: "sm", c: "dimmed", style: { overflowWrap: "anywhere" }, children: description }) : null
107
+ ] }),
108
+ rightSection
109
+ ] }),
110
+ children
111
+ ] });
112
+ }
96
113
  var LEAD_GEN_ROUTE_LINKS = [
97
114
  { label: "Overview", to: "/lead-gen" },
98
115
  { label: "Lists", to: "/lead-gen/lists" },
@@ -1659,109 +1676,108 @@ function WorkflowRunsPanel({ listId, title = "Workflow Runs" }) {
1659
1676
  const openWorkflow = (resourceId) => {
1660
1677
  void navigate({ to: "/operations/resources/workflow/$workflowId", params: { workflowId: resourceId } });
1661
1678
  };
1662
- return /* @__PURE__ */ jsxs(Stack, { gap: "sm", p: "md", children: [
1663
- /* @__PURE__ */ jsx(
1664
- CardHeader,
1665
- {
1666
- icon: /* @__PURE__ */ jsx(IconPlayerPlay, { size: 16 }),
1667
- title,
1668
- rightSection: /* @__PURE__ */ jsx(Tooltip, { label: "Refresh runs", children: /* @__PURE__ */ jsx(
1669
- ActionIcon,
1670
- {
1671
- variant: "subtle",
1672
- size: "sm",
1673
- "aria-label": "Refresh workflow runs",
1674
- loading: executionsQuery.isFetching,
1675
- onClick: () => void executionsQuery.refetch(),
1676
- children: /* @__PURE__ */ jsx(IconRefresh, { size: 14 })
1677
- }
1678
- ) })
1679
- }
1680
- ),
1681
- executionsQuery.isLoading ? /* @__PURE__ */ jsx(Center, { p: "lg", children: /* @__PURE__ */ jsx(Loader, { size: "sm" }) }) : !executions.length ? /* @__PURE__ */ jsx(Text, { size: "sm", c: "dimmed", children: "No workflow runs recorded for this list." }) : /* @__PURE__ */ jsx(Table.ScrollContainer, { minWidth: 720, children: /* @__PURE__ */ jsxs(Table, { highlightOnHover: true, children: [
1682
- /* @__PURE__ */ jsx(Table.Thead, { children: /* @__PURE__ */ jsxs(Table.Tr, { children: [
1683
- /* @__PURE__ */ jsx(Table.Th, {}),
1684
- /* @__PURE__ */ jsx(Table.Th, { children: "Workflow" }),
1685
- /* @__PURE__ */ jsx(Table.Th, { children: "Status" }),
1686
- /* @__PURE__ */ jsx(Table.Th, { children: "Started" }),
1687
- /* @__PURE__ */ jsx(Table.Th, { children: "Completed" }),
1688
- /* @__PURE__ */ jsx(Table.Th, { children: "Duration" })
1689
- ] }) }),
1690
- /* @__PURE__ */ jsx(Table.Tbody, { children: executions.map((execution) => {
1691
- const details = getRunDetails(execution);
1692
- const hasDetails = details.input !== void 0 || details.config !== void 0;
1693
- const expanded = expandedExecutionId === execution.executionId;
1694
- return /* @__PURE__ */ jsxs(Fragment$1, { children: [
1695
- /* @__PURE__ */ jsxs(Table.Tr, { children: [
1696
- /* @__PURE__ */ jsx(Table.Td, { w: 32, children: /* @__PURE__ */ jsx(
1697
- ThemeIcon,
1698
- {
1699
- variant: "light",
1700
- color: "blue",
1701
- size: "md",
1702
- role: hasDetails ? "button" : void 0,
1703
- tabIndex: hasDetails ? 0 : void 0,
1704
- "aria-label": hasDetails ? expanded ? "Collapse run details" : "Expand run details" : void 0,
1705
- onClick: hasDetails ? () => setExpandedExecutionId(expanded ? null : execution.executionId) : void 0,
1706
- onKeyDown: hasDetails ? (event) => {
1707
- if (event.key === "Enter" || event.key === " ") {
1708
- event.preventDefault();
1709
- setExpandedExecutionId(expanded ? null : execution.executionId);
1710
- }
1711
- } : void 0,
1712
- style: {
1713
- cursor: hasDetails ? "pointer" : "default",
1714
- opacity: hasDetails ? 1 : 0.7
1715
- },
1716
- children: expanded ? /* @__PURE__ */ jsx(IconChevronDown, { size: 14 }) : /* @__PURE__ */ jsx(IconChevronRight, { size: 14 })
1717
- }
1718
- ) }),
1719
- /* @__PURE__ */ jsxs(Table.Td, { children: [
1720
- execution.resourceId ? /* @__PURE__ */ jsx(
1721
- Text,
1679
+ return /* @__PURE__ */ jsx(
1680
+ TabSection,
1681
+ {
1682
+ icon: /* @__PURE__ */ jsx(IconPlayerPlay, { size: 16 }),
1683
+ title,
1684
+ description: "Execution history recorded for this lead-gen list.",
1685
+ rightSection: /* @__PURE__ */ jsx(Tooltip, { label: "Refresh runs", children: /* @__PURE__ */ jsx(
1686
+ ActionIcon,
1687
+ {
1688
+ variant: "subtle",
1689
+ size: "sm",
1690
+ "aria-label": "Refresh workflow runs",
1691
+ loading: executionsQuery.isFetching,
1692
+ onClick: () => void executionsQuery.refetch(),
1693
+ children: /* @__PURE__ */ jsx(IconRefresh, { size: 14 })
1694
+ }
1695
+ ) }),
1696
+ children: executionsQuery.isLoading ? /* @__PURE__ */ jsx(Center, { p: "lg", children: /* @__PURE__ */ jsx(Loader, { size: "sm" }) }) : !executions.length ? /* @__PURE__ */ jsx(Text, { size: "sm", c: "dimmed", children: "No workflow runs recorded for this list." }) : /* @__PURE__ */ jsx(Table.ScrollContainer, { minWidth: 720, children: /* @__PURE__ */ jsxs(Table, { highlightOnHover: true, children: [
1697
+ /* @__PURE__ */ jsx(Table.Thead, { children: /* @__PURE__ */ jsxs(Table.Tr, { children: [
1698
+ /* @__PURE__ */ jsx(Table.Th, {}),
1699
+ /* @__PURE__ */ jsx(Table.Th, { children: "Workflow" }),
1700
+ /* @__PURE__ */ jsx(Table.Th, { children: "Status" }),
1701
+ /* @__PURE__ */ jsx(Table.Th, { children: "Started" }),
1702
+ /* @__PURE__ */ jsx(Table.Th, { children: "Completed" }),
1703
+ /* @__PURE__ */ jsx(Table.Th, { children: "Duration" })
1704
+ ] }) }),
1705
+ /* @__PURE__ */ jsx(Table.Tbody, { children: executions.map((execution) => {
1706
+ const details = getRunDetails(execution);
1707
+ const hasDetails = details.input !== void 0 || details.config !== void 0;
1708
+ const expanded = expandedExecutionId === execution.executionId;
1709
+ return /* @__PURE__ */ jsxs(Fragment$1, { children: [
1710
+ /* @__PURE__ */ jsxs(Table.Tr, { children: [
1711
+ /* @__PURE__ */ jsx(Table.Td, { w: 32, children: /* @__PURE__ */ jsx(
1712
+ ThemeIcon,
1722
1713
  {
1723
- fw: 500,
1724
- role: "button",
1725
- tabIndex: 0,
1726
- c: "blue",
1727
- onClick: () => openWorkflow(execution.resourceId),
1728
- onKeyDown: (event) => {
1714
+ variant: "light",
1715
+ color: "blue",
1716
+ size: "md",
1717
+ role: hasDetails ? "button" : void 0,
1718
+ tabIndex: hasDetails ? 0 : void 0,
1719
+ "aria-label": hasDetails ? expanded ? "Collapse run details" : "Expand run details" : void 0,
1720
+ onClick: hasDetails ? () => setExpandedExecutionId(expanded ? null : execution.executionId) : void 0,
1721
+ onKeyDown: hasDetails ? (event) => {
1729
1722
  if (event.key === "Enter" || event.key === " ") {
1730
1723
  event.preventDefault();
1731
- openWorkflow(execution.resourceId);
1724
+ setExpandedExecutionId(expanded ? null : execution.executionId);
1732
1725
  }
1726
+ } : void 0,
1727
+ style: {
1728
+ cursor: hasDetails ? "pointer" : "default",
1729
+ opacity: hasDetails ? 1 : 0.7
1733
1730
  },
1734
- style: { cursor: "pointer" },
1735
- children: execution.resourceId
1731
+ children: expanded ? /* @__PURE__ */ jsx(IconChevronDown, { size: 14 }) : /* @__PURE__ */ jsx(IconChevronRight, { size: 14 })
1736
1732
  }
1737
- ) : /* @__PURE__ */ jsx(Text, { fw: 500, children: "Unknown workflow" }),
1738
- /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", ff: "monospace", children: execution.executionId })
1739
- ] }),
1740
- /* @__PURE__ */ jsx(Table.Td, { children: /* @__PURE__ */ jsx(Badge, { size: "sm", variant: "light", color: getStatusColor2(execution.status), children: execution.status }) }),
1741
- /* @__PURE__ */ jsx(Table.Td, { children: formatDateTime2(execution.createdAt) }),
1742
- /* @__PURE__ */ jsx(Table.Td, { children: formatDateTime2(execution.completedAt) }),
1743
- /* @__PURE__ */ jsx(Table.Td, { children: formatDuration(execution.durationMs) })
1744
- ] }),
1745
- /* @__PURE__ */ jsx(Table.Tr, { children: /* @__PURE__ */ jsx(Table.Td, { colSpan: 6, p: 0, children: /* @__PURE__ */ jsx(Collapse, { in: expanded, children: /* @__PURE__ */ jsxs(Stack, { gap: "sm", p: "sm", children: [
1746
- details.input !== void 0 ? /* @__PURE__ */ jsxs(Stack, { gap: 4, children: [
1747
- /* @__PURE__ */ jsxs(Group, { gap: "xs", children: [
1748
- /* @__PURE__ */ jsx(Text, { size: "sm", fw: 600, children: "Input" }),
1749
- getSummaryKeys(details.input).map((key) => /* @__PURE__ */ jsx(Badge, { size: "xs", variant: "light", color: "gray", children: key }, key))
1750
- ] }),
1751
- /* @__PURE__ */ jsx(JsonViewer, { data: details.input, maxHeight: 220, fontSize: "0.75rem" })
1752
- ] }) : null,
1753
- details.config !== void 0 ? /* @__PURE__ */ jsxs(Stack, { gap: 4, children: [
1754
- /* @__PURE__ */ jsxs(Group, { gap: "xs", children: [
1755
- /* @__PURE__ */ jsx(Text, { size: "sm", fw: 600, children: "Config" }),
1756
- getSummaryKeys(details.config).map((key) => /* @__PURE__ */ jsx(Badge, { size: "xs", variant: "light", color: "gray", children: key }, key))
1733
+ ) }),
1734
+ /* @__PURE__ */ jsxs(Table.Td, { children: [
1735
+ execution.resourceId ? /* @__PURE__ */ jsx(
1736
+ Text,
1737
+ {
1738
+ fw: 500,
1739
+ role: "button",
1740
+ tabIndex: 0,
1741
+ c: "blue",
1742
+ onClick: () => openWorkflow(execution.resourceId),
1743
+ onKeyDown: (event) => {
1744
+ if (event.key === "Enter" || event.key === " ") {
1745
+ event.preventDefault();
1746
+ openWorkflow(execution.resourceId);
1747
+ }
1748
+ },
1749
+ style: { cursor: "pointer" },
1750
+ children: execution.resourceId
1751
+ }
1752
+ ) : /* @__PURE__ */ jsx(Text, { fw: 500, children: "Unknown workflow" }),
1753
+ /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", ff: "monospace", children: execution.executionId })
1757
1754
  ] }),
1758
- /* @__PURE__ */ jsx(JsonViewer, { data: details.config, maxHeight: 220, fontSize: "0.75rem" })
1759
- ] }) : null
1760
- ] }) }) }) })
1761
- ] }, execution.executionId);
1762
- }) })
1763
- ] }) })
1764
- ] });
1755
+ /* @__PURE__ */ jsx(Table.Td, { children: /* @__PURE__ */ jsx(Badge, { size: "sm", variant: "light", color: getStatusColor2(execution.status), children: execution.status }) }),
1756
+ /* @__PURE__ */ jsx(Table.Td, { children: formatDateTime2(execution.createdAt) }),
1757
+ /* @__PURE__ */ jsx(Table.Td, { children: formatDateTime2(execution.completedAt) }),
1758
+ /* @__PURE__ */ jsx(Table.Td, { children: formatDuration(execution.durationMs) })
1759
+ ] }),
1760
+ /* @__PURE__ */ jsx(Table.Tr, { children: /* @__PURE__ */ jsx(Table.Td, { colSpan: 6, p: 0, children: /* @__PURE__ */ jsx(Collapse, { in: expanded, children: /* @__PURE__ */ jsxs(Stack, { gap: "sm", p: "sm", children: [
1761
+ details.input !== void 0 ? /* @__PURE__ */ jsxs(Stack, { gap: 4, children: [
1762
+ /* @__PURE__ */ jsxs(Group, { gap: "xs", children: [
1763
+ /* @__PURE__ */ jsx(Text, { size: "sm", fw: 600, children: "Input" }),
1764
+ getSummaryKeys(details.input).map((key) => /* @__PURE__ */ jsx(Badge, { size: "xs", variant: "light", color: "gray", children: key }, key))
1765
+ ] }),
1766
+ /* @__PURE__ */ jsx(JsonViewer, { data: details.input, maxHeight: 220, fontSize: "0.75rem" })
1767
+ ] }) : null,
1768
+ details.config !== void 0 ? /* @__PURE__ */ jsxs(Stack, { gap: 4, children: [
1769
+ /* @__PURE__ */ jsxs(Group, { gap: "xs", children: [
1770
+ /* @__PURE__ */ jsx(Text, { size: "sm", fw: 600, children: "Config" }),
1771
+ getSummaryKeys(details.config).map((key) => /* @__PURE__ */ jsx(Badge, { size: "xs", variant: "light", color: "gray", children: key }, key))
1772
+ ] }),
1773
+ /* @__PURE__ */ jsx(JsonViewer, { data: details.config, maxHeight: 220, fontSize: "0.75rem" })
1774
+ ] }) : null
1775
+ ] }) }) }) })
1776
+ ] }, execution.executionId);
1777
+ }) })
1778
+ ] }) })
1779
+ }
1780
+ );
1765
1781
  }
1766
1782
  var EMPTY_SELECTION = {
1767
1783
  selectedCompanyIds: [],
@@ -2221,6 +2237,49 @@ function getMemberStateColor2(stateKey) {
2221
2237
  return "gray";
2222
2238
  }
2223
2239
  }
2240
+ function asRecord(value) {
2241
+ return value && typeof value === "object" && !Array.isArray(value) ? value : {};
2242
+ }
2243
+ function getRunStatusColor(status) {
2244
+ switch (status) {
2245
+ case "completed":
2246
+ case "success":
2247
+ case "succeeded":
2248
+ return "green";
2249
+ case "running":
2250
+ case "pending":
2251
+ case "queued":
2252
+ return "blue";
2253
+ case "failed":
2254
+ case "error":
2255
+ case "cancelled":
2256
+ return "red";
2257
+ default:
2258
+ return "gray";
2259
+ }
2260
+ }
2261
+ function getRunInput(run) {
2262
+ const payload = asRecord(run.payload);
2263
+ return run.input ?? run.inputs ?? payload.input ?? payload.inputs;
2264
+ }
2265
+ function getPersistedStepConfig(list, capabilityKey) {
2266
+ return capabilityKey ? asRecord(list.metadata.stepConfig?.[capabilityKey]) : {};
2267
+ }
2268
+ function getDefaultStepInput(list, action) {
2269
+ return asRecord(action?.defaultInput?.(list));
2270
+ }
2271
+ function getInitialStepConfig(list, action, capabilityKey) {
2272
+ const persistedConfig = capabilityKey ? list.metadata.stepConfig?.[capabilityKey] : void 0;
2273
+ if (persistedConfig !== void 0) return asRecord(persistedConfig);
2274
+ return getDefaultStepInput(list, action);
2275
+ }
2276
+ function mergeStepRunInput(list, action, capabilityKey, formStateAtSubmit) {
2277
+ return {
2278
+ ...getDefaultStepInput(list, action),
2279
+ ...getPersistedStepConfig(list, capabilityKey),
2280
+ ...formStateAtSubmit
2281
+ };
2282
+ }
2224
2283
  var ORPHAN_STAGE_ORDER = 9999;
2225
2284
  var EMPTY_SELECTION2 = {
2226
2285
  selectedCompanyIds: [],
@@ -2627,19 +2686,26 @@ function ListConfigCard({ list }) {
2627
2686
  }
2628
2687
  function OverviewTab({ list, progress }) {
2629
2688
  const hasMetadata = list.metadata && Object.keys(list.metadata).length > 0;
2630
- return /* @__PURE__ */ jsxs(Stack, { gap: "md", p: "md", children: [
2631
- /* @__PURE__ */ jsx(CardHeader, { icon: /* @__PURE__ */ jsx(IconBuilding, { size: 16 }), title: "Overview" }),
2632
- /* @__PURE__ */ jsxs(SimpleGrid, { cols: { base: 1, sm: 2 }, children: [
2633
- /* @__PURE__ */ jsx(StatCard, { label: "Companies", value: progress.totalCompanies, icon: IconBuilding }),
2634
- /* @__PURE__ */ jsx(StatCard, { label: "Members", value: progress.totalMembers, icon: IconUsers })
2635
- ] }),
2636
- /* @__PURE__ */ jsx(PipelineStagesCard, { list, progress }),
2637
- /* @__PURE__ */ jsx(ListConfigCard, { list }),
2638
- hasMetadata && /* @__PURE__ */ jsx(Card, { withBorder: true, children: /* @__PURE__ */ jsxs(Stack, { gap: "xs", children: [
2639
- /* @__PURE__ */ jsx(Title, { order: 5, children: "Metadata / Qualification Signals" }),
2640
- /* @__PURE__ */ jsx(JsonViewer, { data: list.metadata, maxHeight: 320 })
2641
- ] }) })
2642
- ] });
2689
+ return /* @__PURE__ */ jsxs(
2690
+ TabSection,
2691
+ {
2692
+ icon: /* @__PURE__ */ jsx(IconBuilding, { size: 16 }),
2693
+ title: "Overview",
2694
+ description: "Configuration, progress, and source metadata for this list.",
2695
+ children: [
2696
+ /* @__PURE__ */ jsxs(SimpleGrid, { cols: { base: 1, sm: 2 }, children: [
2697
+ /* @__PURE__ */ jsx(StatCard, { label: "Companies", value: progress.totalCompanies, icon: IconBuilding }),
2698
+ /* @__PURE__ */ jsx(StatCard, { label: "Members", value: progress.totalMembers, icon: IconUsers })
2699
+ ] }),
2700
+ /* @__PURE__ */ jsx(PipelineStagesCard, { list, progress }),
2701
+ /* @__PURE__ */ jsx(ListConfigCard, { list }),
2702
+ hasMetadata && /* @__PURE__ */ jsx(Card, { withBorder: true, children: /* @__PURE__ */ jsxs(Stack, { gap: "xs", children: [
2703
+ /* @__PURE__ */ jsx(Title, { order: 5, children: "Metadata / Qualification Signals" }),
2704
+ /* @__PURE__ */ jsx(JsonViewer, { data: list.metadata, maxHeight: 320 })
2705
+ ] }) })
2706
+ ]
2707
+ }
2708
+ );
2643
2709
  }
2644
2710
  function getBuildStatusLabel(status) {
2645
2711
  switch (status) {
@@ -2747,25 +2813,6 @@ function BuildStepProgressBar({ step }) {
2747
2813
  }
2748
2814
  );
2749
2815
  }
2750
- function pluralize(value, singular, plural = `${singular}s`) {
2751
- return `${value} ${value === 1 ? singular : plural}`;
2752
- }
2753
- function getStepEntityLabel(step, value) {
2754
- if (step.primaryEntity === "company") return pluralize(value, "company", "companies");
2755
- if (step.primaryEntity === "contact") return pluralize(value, "contact");
2756
- return pluralize(value, "record");
2757
- }
2758
- function getStepActionSummary(step) {
2759
- if (step.failed > 0) {
2760
- return `${getStepEntityLabel(step, step.failed)} ${step.failed === 1 ? "needs" : "need"} retry before the next step can continue.`;
2761
- }
2762
- if (step.ready > 0) {
2763
- return `${getStepEntityLabel(step, step.ready)} ${step.ready === 1 ? "is" : "are"} ready for the next bounded run.`;
2764
- }
2765
- if (step.blocked > 0) return step.emptyBlockedText;
2766
- if (step.complete > 0) return `${step.label} is complete for the current cohort.`;
2767
- return "No runnable records are available for this step.";
2768
- }
2769
2816
  function getStepCompactSummary(step) {
2770
2817
  const parts = [
2771
2818
  step.complete > 0 ? `${step.complete} complete` : null,
@@ -2779,6 +2826,7 @@ function getDisplayStep(steps, recommendedStep) {
2779
2826
  return recommendedStep ?? steps.find((step) => step.status !== "complete") ?? steps[steps.length - 1] ?? null;
2780
2827
  }
2781
2828
  function BuildTab({
2829
+ list,
2782
2830
  steps,
2783
2831
  recommendedStep,
2784
2832
  onRunStep,
@@ -2786,150 +2834,189 @@ function BuildTab({
2786
2834
  onViewRuns
2787
2835
  }) {
2788
2836
  const [selectedStepId, setSelectedStepId] = useState(null);
2837
+ const [stepConfigFormState, setStepConfigFormState] = useState({});
2838
+ const updateListConfigMutation = useUpdateListConfig(list.id);
2789
2839
  const currentStep = getDisplayStep(steps, recommendedStep);
2790
2840
  const selectedStep = steps.find((step) => step.id === selectedStepId) ?? currentStep;
2791
- const currentStepIndex = currentStep ? steps.findIndex((step) => step.id === currentStep.id) : -1;
2792
2841
  const selectedStepIndex = selectedStep ? steps.findIndex((step) => step.id === selectedStep.id) : -1;
2793
2842
  const selectedActionKind = selectedStep?.nextActionKind ?? "none";
2843
+ const selectedCapabilityKey = selectedStep?.action?.capabilityKey ?? selectedStep?.capabilityKey;
2844
+ const selectedResourceId = selectedStep?.action?.resourceId ?? null;
2845
+ const ConfigForm = selectedStep?.action?.ConfigForm;
2846
+ const recentRunsQuery = useListExecutions(list.id, { resourceId: selectedResourceId, limit: 5 });
2847
+ const recentRuns = useMemo(() => recentRunsQuery.data ?? [], [recentRunsQuery.data]);
2794
2848
  const canRunSelectedAction = !!selectedStep?.action && (selectedActionKind === "retry_failed" || selectedActionKind === "run_next_batch");
2795
2849
  const selectedActionIcon = selectedActionKind === "retry_failed" ? /* @__PURE__ */ jsx(IconRefresh, { size: 14 }) : /* @__PURE__ */ jsx(IconPlayerPlay, { size: 14 });
2850
+ useEffect(() => {
2851
+ setStepConfigFormState(getInitialStepConfig(list, selectedStep?.action, selectedCapabilityKey));
2852
+ }, [list, selectedCapabilityKey, selectedStep?.action]);
2853
+ const handleSaveStepConfig = () => {
2854
+ if (!selectedCapabilityKey) return;
2855
+ updateListConfigMutation.mutate({
2856
+ stepConfig: {
2857
+ [selectedCapabilityKey]: stepConfigFormState
2858
+ }
2859
+ });
2860
+ };
2796
2861
  const handleSelectedAction = () => {
2797
2862
  if (!selectedStep || !canRunSelectedAction) return;
2863
+ const submittedConfig = ConfigForm ? stepConfigFormState : {};
2798
2864
  if (selectedActionKind === "retry_failed") {
2799
- onRetryStep(selectedStep);
2865
+ onRetryStep(selectedStep, submittedConfig);
2800
2866
  return;
2801
2867
  }
2802
- onRunStep(selectedStep);
2868
+ onRunStep(selectedStep, submittedConfig);
2803
2869
  };
2804
- return /* @__PURE__ */ jsxs(Stack, { gap: "md", p: "md", children: [
2805
- /* @__PURE__ */ jsxs(Stack, { gap: 4, children: [
2806
- /* @__PURE__ */ jsx(CardHeader, { icon: /* @__PURE__ */ jsx(IconBolt, { size: 16 }), title: "Build" }),
2807
- /* @__PURE__ */ jsx(Text, { size: "sm", c: "dimmed", children: currentStep ? `${currentStep.label} is the current step in this list build.` : "No build steps are available for this list." })
2808
- ] }),
2809
- currentStep ? /* @__PURE__ */ jsx(Card, { withBorder: true, children: /* @__PURE__ */ jsxs(Stack, { gap: "xs", style: { minWidth: 0 }, children: [
2810
- /* @__PURE__ */ jsxs(Group, { gap: "xs", children: [
2811
- /* @__PURE__ */ jsx(
2812
- StatusPill,
2813
- {
2814
- label: `Step ${currentStepIndex + 1} of ${steps.length}`,
2815
- tone: currentStep.status === "failed" ? "failed" : "ready"
2816
- }
2817
- ),
2818
- /* @__PURE__ */ jsx(StatusPill, { label: getBuildStatusLabel(currentStep.status), tone: currentStep.status })
2819
- ] }),
2820
- /* @__PURE__ */ jsxs(Stack, { gap: 4, children: [
2821
- /* @__PURE__ */ jsx(Title, { order: 4, children: currentStep.label }),
2822
- /* @__PURE__ */ jsx(Text, { size: "sm", c: "dimmed", children: getStepActionSummary(currentStep) }),
2823
- currentStep.recommendedAction?.defaultSize !== void 0 && currentStep.recommendedAction.maxSize !== void 0 ? /* @__PURE__ */ jsxs(Text, { size: "xs", c: "dimmed", children: [
2824
- "Runs up to ",
2825
- currentStep.recommendedAction.defaultSize,
2826
- " by default,",
2827
- " ",
2828
- currentStep.recommendedAction.maxSize,
2829
- " max."
2830
- ] }) : null,
2831
- !currentStep.action && (currentStep.ready > 0 || currentStep.failed > 0) ? /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: "No workflow is mapped for this step yet." }) : null
2832
- ] })
2833
- ] }) }) : null,
2834
- /* @__PURE__ */ jsxs(SimpleGrid, { cols: { base: 1, md: 2 }, spacing: "md", children: [
2835
- /* @__PURE__ */ jsx(Stack, { gap: "xs", children: steps.map((step, index) => {
2836
- const isCurrent = currentStep?.id === step.id;
2837
- const isSelected = selectedStep?.id === step.id;
2838
- const isWaiting = step.status === "blocked";
2839
- const isPassiveWaiting = isWaiting && !isSelected && !isCurrent;
2840
- const stepTone = isSelected || isCurrent ? step.status : step.status === "complete" || isWaiting ? step.status : "neutral";
2841
- return /* @__PURE__ */ jsx(
2842
- UnstyledButton,
2843
- {
2844
- onClick: () => setSelectedStepId(step.id),
2845
- style: {
2846
- backgroundColor: isSelected ? "var(--active-background)" : isPassiveWaiting ? "color-mix(in srgb, var(--color-surface-hover) 38%, transparent)" : "transparent",
2847
- border: isSelected ? "var(--active-border)" : "1px solid var(--color-border)",
2848
- borderStyle: isPassiveWaiting ? "dashed" : "solid",
2849
- borderRadius: 8,
2850
- display: "block",
2851
- opacity: isPassiveWaiting ? 0.72 : 1,
2852
- padding: 12,
2853
- textAlign: "left",
2854
- width: "100%"
2855
- },
2856
- children: /* @__PURE__ */ jsxs(Group, { gap: "sm", align: "flex-start", wrap: "nowrap", children: [
2857
- /* @__PURE__ */ jsx(
2858
- Box,
2859
- {
2860
- w: 28,
2861
- h: 28,
2862
- style: {
2863
- alignItems: "center",
2864
- ...getBuildToneStyle(stepTone),
2865
- borderRadius: 999,
2866
- borderStyle: "solid",
2867
- borderWidth: 1,
2868
- display: "flex",
2869
- flexShrink: 0,
2870
- fontWeight: 700,
2871
- justifyContent: "center"
2872
- },
2873
- children: index + 1
2874
- }
2875
- ),
2876
- /* @__PURE__ */ jsxs(Stack, { gap: 3, style: { minWidth: 0, flex: 1 }, children: [
2877
- /* @__PURE__ */ jsxs(Group, { gap: "xs", justify: "space-between", wrap: "nowrap", children: [
2878
- /* @__PURE__ */ jsx(Text, { fw: 700, c: isPassiveWaiting ? "dimmed" : void 0, truncate: true, children: step.label }),
2879
- isCurrent ? /* @__PURE__ */ jsx(StatusPill, { label: "Current", tone: step.status }) : null,
2880
- !isCurrent && isWaiting ? /* @__PURE__ */ jsx(StatusPill, { label: "Waiting", tone: "blocked" }) : null
2881
- ] }),
2882
- /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: getStepCompactSummary(step) })
2870
+ const loadRecentRunInput = (run) => {
2871
+ setStepConfigFormState(asRecord(getRunInput(run)));
2872
+ };
2873
+ return /* @__PURE__ */ jsx(
2874
+ TabSection,
2875
+ {
2876
+ icon: /* @__PURE__ */ jsx(IconBolt, { size: 16 }),
2877
+ title: "Build",
2878
+ description: currentStep ? `${currentStep.label} is the current step in this list build.` : "No build steps are available for this list.",
2879
+ children: /* @__PURE__ */ jsxs(SimpleGrid, { cols: { base: 1, md: 2 }, spacing: "md", children: [
2880
+ /* @__PURE__ */ jsx(Stack, { gap: "xs", children: steps.map((step, index) => {
2881
+ const isCurrent = currentStep?.id === step.id;
2882
+ const isSelected = selectedStep?.id === step.id;
2883
+ const isWaiting = step.status === "blocked";
2884
+ const isPassiveWaiting = isWaiting && !isSelected && !isCurrent;
2885
+ const stepTone = isSelected || isCurrent ? step.status : step.status === "complete" || isWaiting ? step.status : "neutral";
2886
+ return /* @__PURE__ */ jsx(
2887
+ UnstyledButton,
2888
+ {
2889
+ onClick: () => setSelectedStepId(step.id),
2890
+ style: {
2891
+ backgroundColor: isSelected ? "var(--active-background)" : isPassiveWaiting ? "color-mix(in srgb, var(--color-surface-hover) 38%, transparent)" : "transparent",
2892
+ border: isSelected ? "var(--active-border)" : "1px solid var(--color-border)",
2893
+ borderStyle: isPassiveWaiting ? "dashed" : "solid",
2894
+ borderRadius: 8,
2895
+ display: "block",
2896
+ opacity: isPassiveWaiting ? 0.72 : 1,
2897
+ padding: 12,
2898
+ textAlign: "left",
2899
+ width: "100%"
2900
+ },
2901
+ children: /* @__PURE__ */ jsxs(Group, { gap: "sm", align: "flex-start", wrap: "nowrap", children: [
2902
+ /* @__PURE__ */ jsx(
2903
+ Box,
2904
+ {
2905
+ w: 28,
2906
+ h: 28,
2907
+ style: {
2908
+ alignItems: "center",
2909
+ ...getBuildToneStyle(stepTone),
2910
+ borderRadius: 999,
2911
+ borderStyle: "solid",
2912
+ borderWidth: 1,
2913
+ display: "flex",
2914
+ flexShrink: 0,
2915
+ fontWeight: 700,
2916
+ justifyContent: "center"
2917
+ },
2918
+ children: index + 1
2919
+ }
2920
+ ),
2921
+ /* @__PURE__ */ jsxs(Stack, { gap: 3, style: { minWidth: 0, flex: 1 }, children: [
2922
+ /* @__PURE__ */ jsxs(Group, { gap: "xs", justify: "space-between", wrap: "nowrap", children: [
2923
+ /* @__PURE__ */ jsx(Text, { fw: 700, c: isPassiveWaiting ? "dimmed" : void 0, truncate: true, children: step.label }),
2924
+ isCurrent ? /* @__PURE__ */ jsx(StatusPill, { label: "Current", tone: step.status }) : null,
2925
+ !isCurrent && isWaiting ? /* @__PURE__ */ jsx(StatusPill, { label: "Waiting", tone: "blocked" }) : null
2926
+ ] }),
2927
+ /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: getStepCompactSummary(step) })
2928
+ ] })
2883
2929
  ] })
2884
- ] })
2885
- },
2886
- step.id
2887
- );
2888
- }) }),
2889
- selectedStep ? /* @__PURE__ */ jsx(Card, { withBorder: true, children: /* @__PURE__ */ jsxs(Stack, { gap: "md", children: [
2890
- /* @__PURE__ */ jsxs(Group, { justify: "space-between", align: "flex-start", gap: "sm", children: [
2891
- /* @__PURE__ */ jsxs(Stack, { gap: 2, style: { minWidth: 0 }, children: [
2892
- /* @__PURE__ */ jsxs(Text, { size: "xs", c: "dimmed", fw: 700, tt: "uppercase", children: [
2893
- "Step ",
2894
- selectedStepIndex + 1,
2895
- " details"
2930
+ },
2931
+ step.id
2932
+ );
2933
+ }) }),
2934
+ selectedStep ? /* @__PURE__ */ jsx(Card, { withBorder: true, children: /* @__PURE__ */ jsxs(Stack, { gap: "md", children: [
2935
+ /* @__PURE__ */ jsxs(Group, { justify: "space-between", align: "flex-start", gap: "sm", children: [
2936
+ /* @__PURE__ */ jsxs(Stack, { gap: 2, style: { minWidth: 0 }, children: [
2937
+ /* @__PURE__ */ jsxs(Text, { size: "xs", c: "dimmed", fw: 700, tt: "uppercase", children: [
2938
+ "Step ",
2939
+ selectedStepIndex + 1,
2940
+ " details"
2941
+ ] }),
2942
+ /* @__PURE__ */ jsx(Title, { order: 5, children: selectedStep.label })
2896
2943
  ] }),
2897
- /* @__PURE__ */ jsx(Title, { order: 5, children: selectedStep.label })
2944
+ /* @__PURE__ */ jsx(StatusPill, { label: getBuildStatusLabel(selectedStep.status), tone: selectedStep.status })
2898
2945
  ] }),
2899
- /* @__PURE__ */ jsx(StatusPill, { label: getBuildStatusLabel(selectedStep.status), tone: selectedStep.status })
2900
- ] }),
2901
- /* @__PURE__ */ jsx(Text, { size: "sm", c: "dimmed", children: selectedStep.description }),
2902
- selectedStep.status === "blocked" ? /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: selectedStep.emptyBlockedText }) : null,
2903
- /* @__PURE__ */ jsxs(SimpleGrid, { cols: { base: 2, sm: 4 }, spacing: "xs", children: [
2904
- /* @__PURE__ */ jsx(CountBadge, { label: "Ready", value: selectedStep.ready, tone: "ready" }),
2905
- /* @__PURE__ */ jsx(CountBadge, { label: "Complete", value: selectedStep.complete, tone: "complete" }),
2906
- /* @__PURE__ */ jsx(CountBadge, { label: "Failed", value: selectedStep.failed, tone: "failed" }),
2907
- /* @__PURE__ */ jsx(CountBadge, { label: "Waiting", value: selectedStep.blocked, tone: "blocked" })
2908
- ] }),
2909
- /* @__PURE__ */ jsx(BuildStepProgressBar, { step: selectedStep }),
2910
- selectedStep.recommendedAction?.defaultSize !== void 0 && selectedStep.recommendedAction.maxSize !== void 0 ? /* @__PURE__ */ jsxs(Text, { size: "xs", c: "dimmed", children: [
2911
- "Batch size: ",
2912
- selectedStep.recommendedAction.defaultSize,
2913
- " default,",
2914
- " ",
2915
- selectedStep.recommendedAction.maxSize,
2916
- " max."
2917
- ] }) : null,
2918
- /* @__PURE__ */ jsxs(Group, { gap: "xs", justify: "flex-end", wrap: "nowrap", children: [
2919
- /* @__PURE__ */ jsx(
2920
- Button,
2921
- {
2922
- leftSection: selectedActionIcon,
2923
- disabled: !canRunSelectedAction,
2924
- onClick: handleSelectedAction,
2925
- children: selectedActionKind === "none" ? "No action" : getStepActionLabel(selectedActionKind)
2926
- }
2927
- ),
2928
- /* @__PURE__ */ jsx(Button, { variant: "light", leftSection: /* @__PURE__ */ jsx(IconPlayerPlay, { size: 14 }), onClick: onViewRuns, children: "View runs" })
2929
- ] })
2930
- ] }) }) : null
2931
- ] })
2932
- ] });
2946
+ /* @__PURE__ */ jsx(Text, { size: "sm", c: "dimmed", children: selectedStep.description }),
2947
+ selectedStep.status === "blocked" ? /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: selectedStep.emptyBlockedText }) : null,
2948
+ /* @__PURE__ */ jsxs(SimpleGrid, { cols: { base: 2, sm: 4 }, spacing: "xs", children: [
2949
+ /* @__PURE__ */ jsx(CountBadge, { label: "Ready", value: selectedStep.ready, tone: "ready" }),
2950
+ /* @__PURE__ */ jsx(CountBadge, { label: "Complete", value: selectedStep.complete, tone: "complete" }),
2951
+ /* @__PURE__ */ jsx(CountBadge, { label: "Failed", value: selectedStep.failed, tone: "failed" }),
2952
+ /* @__PURE__ */ jsx(CountBadge, { label: "Waiting", value: selectedStep.blocked, tone: "blocked" })
2953
+ ] }),
2954
+ /* @__PURE__ */ jsx(BuildStepProgressBar, { step: selectedStep }),
2955
+ selectedStep.recommendedAction?.defaultSize !== void 0 && selectedStep.recommendedAction.maxSize !== void 0 ? /* @__PURE__ */ jsxs(Text, { size: "xs", c: "dimmed", children: [
2956
+ "Batch size: ",
2957
+ selectedStep.recommendedAction.defaultSize,
2958
+ " default,",
2959
+ " ",
2960
+ selectedStep.recommendedAction.maxSize,
2961
+ " max."
2962
+ ] }) : null,
2963
+ ConfigForm ? /* @__PURE__ */ jsxs(Stack, { gap: "sm", children: [
2964
+ /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", fw: 700, tt: "uppercase", children: "Configure" }),
2965
+ /* @__PURE__ */ jsx(ConfigForm, { value: stepConfigFormState, onChange: setStepConfigFormState }),
2966
+ /* @__PURE__ */ jsx(Group, { justify: "flex-end", children: /* @__PURE__ */ jsx(
2967
+ Button,
2968
+ {
2969
+ size: "xs",
2970
+ variant: "light",
2971
+ loading: updateListConfigMutation.isPending,
2972
+ onClick: handleSaveStepConfig,
2973
+ children: "Save"
2974
+ }
2975
+ ) })
2976
+ ] }) : null,
2977
+ /* @__PURE__ */ jsxs(Group, { gap: "xs", justify: "flex-end", wrap: "nowrap", children: [
2978
+ /* @__PURE__ */ jsx(
2979
+ Button,
2980
+ {
2981
+ leftSection: selectedActionIcon,
2982
+ disabled: !canRunSelectedAction,
2983
+ onClick: handleSelectedAction,
2984
+ children: selectedActionKind === "none" ? "No action" : getStepActionLabel(selectedActionKind)
2985
+ }
2986
+ ),
2987
+ /* @__PURE__ */ jsx(Button, { variant: "light", leftSection: /* @__PURE__ */ jsx(IconPlayerPlay, { size: 14 }), onClick: onViewRuns, children: "View runs" })
2988
+ ] }),
2989
+ selectedResourceId ? /* @__PURE__ */ jsxs(Stack, { gap: "xs", children: [
2990
+ /* @__PURE__ */ jsxs(Group, { justify: "space-between", gap: "xs", children: [
2991
+ /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", fw: 700, tt: "uppercase", children: "Recent runs" }),
2992
+ recentRunsQuery.isFetching ? /* @__PURE__ */ jsx(Loader, { size: "xs" }) : null
2993
+ ] }),
2994
+ !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) => /* @__PURE__ */ jsx(
2995
+ UnstyledButton,
2996
+ {
2997
+ onClick: () => loadRecentRunInput(run),
2998
+ style: {
2999
+ border: "1px solid var(--color-border)",
3000
+ borderRadius: 8,
3001
+ padding: "8px 10px",
3002
+ textAlign: "left",
3003
+ width: "100%"
3004
+ },
3005
+ children: /* @__PURE__ */ jsxs(Group, { justify: "space-between", gap: "xs", wrap: "nowrap", children: [
3006
+ /* @__PURE__ */ jsxs(Stack, { gap: 2, style: { minWidth: 0 }, children: [
3007
+ /* @__PURE__ */ jsx(Text, { size: "sm", fw: 600, truncate: true, children: formatDateTime4(run.createdAt) }),
3008
+ /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", ff: "monospace", truncate: true, children: run.executionId })
3009
+ ] }),
3010
+ /* @__PURE__ */ jsx(Badge, { size: "sm", variant: "light", color: getRunStatusColor(run.status), children: run.status })
3011
+ ] })
3012
+ },
3013
+ run.executionId
3014
+ )) })
3015
+ ] }) : null
3016
+ ] }) }) : null
3017
+ ] })
3018
+ }
3019
+ );
2933
3020
  }
2934
3021
  function MembersTab({
2935
3022
  listId,
@@ -2941,75 +3028,76 @@ function MembersTab({
2941
3028
  const companiesQuery = useCompanies({ listId, limit: 100, offset: 0 });
2942
3029
  const contacts = contactsQuery.data?.data ?? [];
2943
3030
  const companies = companiesQuery.data?.data ?? [];
2944
- return /* @__PURE__ */ jsxs(Stack, { gap: "sm", p: "md", children: [
2945
- /* @__PURE__ */ jsx(
2946
- CardHeader,
2947
- {
2948
- icon: /* @__PURE__ */ jsx(IconAddressBook, { size: 16 }),
2949
- title: "Members",
2950
- rightSection: /* @__PURE__ */ jsx(
2951
- SegmentedControl,
2952
- {
2953
- value: memberTab,
2954
- onChange: (value) => setMemberTab(value),
2955
- size: "xs",
2956
- data: [
2957
- { label: `Members (${progress.totalMembers})`, value: "contacts" },
2958
- { label: `Companies (${progress.totalCompanies})`, value: "companies" }
2959
- ]
2960
- }
2961
- )
2962
- }
2963
- ),
2964
- memberTab === "contacts" && /* @__PURE__ */ jsx(Fragment, { children: contactsQuery.isLoading ? /* @__PURE__ */ jsx(Center, { p: "md", children: /* @__PURE__ */ jsx(Loader, { size: "sm" }) }) : !contacts.length ? /* @__PURE__ */ jsx(Text, { size: "sm", c: "dimmed", children: "No contacts attached to this list yet." }) : /* @__PURE__ */ jsxs(Table, { highlightOnHover: true, children: [
2965
- /* @__PURE__ */ jsx(Table.Thead, { children: /* @__PURE__ */ jsxs(Table.Tr, { children: [
2966
- /* @__PURE__ */ jsx(Table.Th, { children: "Name" }),
2967
- /* @__PURE__ */ jsx(Table.Th, { children: "Email" }),
2968
- /* @__PURE__ */ jsx(Table.Th, { children: "Title" }),
2969
- /* @__PURE__ */ jsx(Table.Th, { children: "Company" }),
2970
- /* @__PURE__ */ jsx(Table.Th, { children: "Status" }),
2971
- /* @__PURE__ */ jsx(Table.Th, { children: "State" }),
2972
- /* @__PURE__ */ jsx(Table.Th, { children: "Created" })
2973
- ] }) }),
2974
- /* @__PURE__ */ jsx(Table.Tbody, { children: contacts.map((contact) => {
2975
- const handleRowClick = () => onMemberClick?.(contact.id, "contact");
2976
- const memberState = contact.stateKey ?? null;
2977
- return /* @__PURE__ */ jsxs(Table.Tr, { onClick: handleRowClick, style: { cursor: "pointer" }, children: [
2978
- /* @__PURE__ */ jsx(Table.Td, { children: /* @__PURE__ */ jsx(Text, { fw: 500, children: contactDisplayName(contact.firstName, contact.lastName) }) }),
2979
- /* @__PURE__ */ jsx(Table.Td, { children: contact.email }),
2980
- /* @__PURE__ */ jsx(Table.Td, { children: contact.title ?? "\u2014" }),
2981
- /* @__PURE__ */ jsx(Table.Td, { children: contact.company?.name ?? "\u2014" }),
2982
- /* @__PURE__ */ jsx(Table.Td, { children: /* @__PURE__ */ jsx(Badge, { size: "sm", variant: "light", color: getStatusColor4(contact.status), children: contact.status }) }),
2983
- /* @__PURE__ */ jsx(Table.Td, { children: memberState ? /* @__PURE__ */ jsx(Badge, { size: "sm", variant: "dot", color: getMemberStateColor2(memberState), children: memberState }) : /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: "\u2014" }) }),
2984
- /* @__PURE__ */ jsx(Table.Td, { children: formatDateTime4(contact.createdAt) })
2985
- ] }, contact.id);
2986
- }) })
2987
- ] }) }),
2988
- memberTab === "companies" && /* @__PURE__ */ jsx(Fragment, { children: companiesQuery.isLoading ? /* @__PURE__ */ jsx(Center, { p: "md", children: /* @__PURE__ */ jsx(Loader, { size: "sm" }) }) : !companies.length ? /* @__PURE__ */ jsx(Text, { size: "sm", c: "dimmed", children: "No companies attached to this list yet." }) : /* @__PURE__ */ jsxs(Table, { highlightOnHover: true, children: [
2989
- /* @__PURE__ */ jsx(Table.Thead, { children: /* @__PURE__ */ jsxs(Table.Tr, { children: [
2990
- /* @__PURE__ */ jsx(Table.Th, { children: "Name" }),
2991
- /* @__PURE__ */ jsx(Table.Th, { children: "Domain" }),
2992
- /* @__PURE__ */ jsx(Table.Th, { children: "Segment" }),
2993
- /* @__PURE__ */ jsx(Table.Th, { children: "Contacts" }),
2994
- /* @__PURE__ */ jsx(Table.Th, { children: "Status" }),
2995
- /* @__PURE__ */ jsx(Table.Th, { children: "State" }),
2996
- /* @__PURE__ */ jsx(Table.Th, { children: "Created" })
2997
- ] }) }),
2998
- /* @__PURE__ */ jsx(Table.Tbody, { children: companies.map((company) => {
2999
- const handleRowClick = () => onMemberClick?.(company.id, "company");
3000
- const memberState = company.stateKey ?? null;
3001
- return /* @__PURE__ */ jsxs(Table.Tr, { onClick: handleRowClick, style: { cursor: "pointer" }, children: [
3002
- /* @__PURE__ */ jsx(Table.Td, { children: /* @__PURE__ */ jsx(Text, { fw: 500, children: company.name }) }),
3003
- /* @__PURE__ */ jsx(Table.Td, { children: company.domain ?? "\u2014" }),
3004
- /* @__PURE__ */ jsx(Table.Td, { children: company.segment ?? "\u2014" }),
3005
- /* @__PURE__ */ jsx(Table.Td, { children: company.contactCount }),
3006
- /* @__PURE__ */ jsx(Table.Td, { children: /* @__PURE__ */ jsx(Badge, { size: "sm", variant: "light", color: getStatusColor4(company.status), children: company.status }) }),
3007
- /* @__PURE__ */ jsx(Table.Td, { children: memberState ? /* @__PURE__ */ jsx(Badge, { size: "sm", variant: "dot", color: getMemberStateColor2(memberState), children: memberState }) : /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: "\u2014" }) }),
3008
- /* @__PURE__ */ jsx(Table.Td, { children: formatDateTime4(company.createdAt) })
3009
- ] }, company.id);
3010
- }) })
3011
- ] }) })
3012
- ] });
3031
+ return /* @__PURE__ */ jsxs(
3032
+ TabSection,
3033
+ {
3034
+ icon: /* @__PURE__ */ jsx(IconAddressBook, { size: 16 }),
3035
+ title: "Members",
3036
+ description: "Contacts and companies attached to this list.",
3037
+ rightSection: /* @__PURE__ */ jsx(
3038
+ SegmentedControl,
3039
+ {
3040
+ value: memberTab,
3041
+ onChange: (value) => setMemberTab(value),
3042
+ size: "xs",
3043
+ data: [
3044
+ { label: `Members (${progress.totalMembers})`, value: "contacts" },
3045
+ { label: `Companies (${progress.totalCompanies})`, value: "companies" }
3046
+ ]
3047
+ }
3048
+ ),
3049
+ children: [
3050
+ memberTab === "contacts" && /* @__PURE__ */ jsx(Fragment, { children: contactsQuery.isLoading ? /* @__PURE__ */ jsx(Center, { p: "md", children: /* @__PURE__ */ jsx(Loader, { size: "sm" }) }) : !contacts.length ? /* @__PURE__ */ jsx(Text, { size: "sm", c: "dimmed", children: "No contacts attached to this list yet." }) : /* @__PURE__ */ jsxs(Table, { highlightOnHover: true, children: [
3051
+ /* @__PURE__ */ jsx(Table.Thead, { children: /* @__PURE__ */ jsxs(Table.Tr, { children: [
3052
+ /* @__PURE__ */ jsx(Table.Th, { children: "Name" }),
3053
+ /* @__PURE__ */ jsx(Table.Th, { children: "Email" }),
3054
+ /* @__PURE__ */ jsx(Table.Th, { children: "Title" }),
3055
+ /* @__PURE__ */ jsx(Table.Th, { children: "Company" }),
3056
+ /* @__PURE__ */ jsx(Table.Th, { children: "Status" }),
3057
+ /* @__PURE__ */ jsx(Table.Th, { children: "State" }),
3058
+ /* @__PURE__ */ jsx(Table.Th, { children: "Created" })
3059
+ ] }) }),
3060
+ /* @__PURE__ */ jsx(Table.Tbody, { children: contacts.map((contact) => {
3061
+ const handleRowClick = () => onMemberClick?.(contact.id, "contact");
3062
+ const memberState = contact.stateKey ?? null;
3063
+ return /* @__PURE__ */ jsxs(Table.Tr, { onClick: handleRowClick, style: { cursor: "pointer" }, children: [
3064
+ /* @__PURE__ */ jsx(Table.Td, { children: /* @__PURE__ */ jsx(Text, { fw: 500, children: contactDisplayName(contact.firstName, contact.lastName) }) }),
3065
+ /* @__PURE__ */ jsx(Table.Td, { children: contact.email }),
3066
+ /* @__PURE__ */ jsx(Table.Td, { children: contact.title ?? "\u2014" }),
3067
+ /* @__PURE__ */ jsx(Table.Td, { children: contact.company?.name ?? "\u2014" }),
3068
+ /* @__PURE__ */ jsx(Table.Td, { children: /* @__PURE__ */ jsx(Badge, { size: "sm", variant: "light", color: getStatusColor4(contact.status), children: contact.status }) }),
3069
+ /* @__PURE__ */ jsx(Table.Td, { children: memberState ? /* @__PURE__ */ jsx(Badge, { size: "sm", variant: "dot", color: getMemberStateColor2(memberState), children: memberState }) : /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: "\u2014" }) }),
3070
+ /* @__PURE__ */ jsx(Table.Td, { children: formatDateTime4(contact.createdAt) })
3071
+ ] }, contact.id);
3072
+ }) })
3073
+ ] }) }),
3074
+ memberTab === "companies" && /* @__PURE__ */ jsx(Fragment, { children: companiesQuery.isLoading ? /* @__PURE__ */ jsx(Center, { p: "md", children: /* @__PURE__ */ jsx(Loader, { size: "sm" }) }) : !companies.length ? /* @__PURE__ */ jsx(Text, { size: "sm", c: "dimmed", children: "No companies attached to this list yet." }) : /* @__PURE__ */ jsxs(Table, { highlightOnHover: true, children: [
3075
+ /* @__PURE__ */ jsx(Table.Thead, { children: /* @__PURE__ */ jsxs(Table.Tr, { children: [
3076
+ /* @__PURE__ */ jsx(Table.Th, { children: "Name" }),
3077
+ /* @__PURE__ */ jsx(Table.Th, { children: "Domain" }),
3078
+ /* @__PURE__ */ jsx(Table.Th, { children: "Segment" }),
3079
+ /* @__PURE__ */ jsx(Table.Th, { children: "Contacts" }),
3080
+ /* @__PURE__ */ jsx(Table.Th, { children: "Status" }),
3081
+ /* @__PURE__ */ jsx(Table.Th, { children: "State" }),
3082
+ /* @__PURE__ */ jsx(Table.Th, { children: "Created" })
3083
+ ] }) }),
3084
+ /* @__PURE__ */ jsx(Table.Tbody, { children: companies.map((company) => {
3085
+ const handleRowClick = () => onMemberClick?.(company.id, "company");
3086
+ const memberState = company.stateKey ?? null;
3087
+ return /* @__PURE__ */ jsxs(Table.Tr, { onClick: handleRowClick, style: { cursor: "pointer" }, children: [
3088
+ /* @__PURE__ */ jsx(Table.Td, { children: /* @__PURE__ */ jsx(Text, { fw: 500, children: company.name }) }),
3089
+ /* @__PURE__ */ jsx(Table.Td, { children: company.domain ?? "\u2014" }),
3090
+ /* @__PURE__ */ jsx(Table.Td, { children: company.segment ?? "\u2014" }),
3091
+ /* @__PURE__ */ jsx(Table.Td, { children: company.contactCount }),
3092
+ /* @__PURE__ */ jsx(Table.Td, { children: /* @__PURE__ */ jsx(Badge, { size: "sm", variant: "light", color: getStatusColor4(company.status), children: company.status }) }),
3093
+ /* @__PURE__ */ jsx(Table.Td, { children: memberState ? /* @__PURE__ */ jsx(Badge, { size: "sm", variant: "dot", color: getMemberStateColor2(memberState), children: memberState }) : /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: "\u2014" }) }),
3094
+ /* @__PURE__ */ jsx(Table.Td, { children: formatDateTime4(company.createdAt) })
3095
+ ] }, company.id);
3096
+ }) })
3097
+ ] }) })
3098
+ ]
3099
+ }
3100
+ );
3013
3101
  }
3014
3102
  function ListDetailHeader({
3015
3103
  title,
@@ -3041,12 +3129,24 @@ function LeadGenListDetailPage({ listId }) {
3041
3129
  const progressQuery = useListProgress(listId);
3042
3130
  const deleteListMutation = useDeleteList();
3043
3131
  const updateListMutation = useUpdateList(listId);
3132
+ const updateListConfigMutation = useUpdateListConfig(listId);
3044
3133
  const [deleteModalOpen, setDeleteModalOpen] = useState(false);
3045
3134
  const [pipelineModalOpen, setPipelineModalOpen] = useState(false);
3046
3135
  const [selectedBuildTemplateId, setSelectedBuildTemplateId] = useState(DEFAULT_PROSPECTING_BUILD_TEMPLATE_ID);
3047
3136
  const [runModalOpen, setRunModalOpen] = useState(false);
3048
3137
  const [activeTab, setActiveTab] = useState("overview");
3049
3138
  const [initialRunResourceId, setInitialRunResourceId] = useState(null);
3139
+ const [pendingStepRunConfig, setPendingStepRunConfig] = useState(null);
3140
+ const runModalActions = useMemo(() => {
3141
+ if (!pendingStepRunConfig) return actions;
3142
+ return actions.map((action) => {
3143
+ if (action.resourceId !== pendingStepRunConfig.resourceId) return action;
3144
+ return {
3145
+ ...action,
3146
+ defaultInput: (nextList) => mergeStepRunInput(nextList, action, pendingStepRunConfig.capabilityKey, pendingStepRunConfig.formStateAtSubmit)
3147
+ };
3148
+ });
3149
+ }, [actions, pendingStepRunConfig]);
3050
3150
  const isLoading = listQuery.isLoading || progressQuery.isLoading;
3051
3151
  const error = listQuery.error ?? progressQuery.error;
3052
3152
  const backButton = /* @__PURE__ */ jsx(
@@ -3117,8 +3217,18 @@ function LeadGenListDetailPage({ listId }) {
3117
3217
  const closeRunModal = () => {
3118
3218
  setRunModalOpen(false);
3119
3219
  setInitialRunResourceId(null);
3220
+ setPendingStepRunConfig(null);
3120
3221
  };
3121
- const openStepRun = (step) => {
3222
+ const openStepRun = (step, formStateAtSubmit) => {
3223
+ if (step.action?.ConfigForm) {
3224
+ setPendingStepRunConfig({
3225
+ resourceId: step.action.resourceId,
3226
+ capabilityKey: step.action.capabilityKey ?? step.capabilityKey,
3227
+ formStateAtSubmit
3228
+ });
3229
+ } else {
3230
+ setPendingStepRunConfig(null);
3231
+ }
3122
3232
  openRunModal(step.action?.resourceId ?? null);
3123
3233
  };
3124
3234
  const handleCopyListCommand = () => {
@@ -3156,6 +3266,16 @@ function LeadGenListDetailPage({ listId }) {
3156
3266
  }
3157
3267
  );
3158
3268
  };
3269
+ const persistSubmittedStepConfig = (resourceId) => {
3270
+ if (!pendingStepRunConfig || pendingStepRunConfig.resourceId !== resourceId || !pendingStepRunConfig.capabilityKey) {
3271
+ return;
3272
+ }
3273
+ updateListConfigMutation.mutate({
3274
+ stepConfig: {
3275
+ [pendingStepRunConfig.capabilityKey]: pendingStepRunConfig.formStateAtSubmit
3276
+ }
3277
+ });
3278
+ };
3159
3279
  return /* @__PURE__ */ jsxs(SubshellContentContainer, { children: [
3160
3280
  /* @__PURE__ */ jsx(PageContainer, { children: /* @__PURE__ */ jsxs(Stack, { children: [
3161
3281
  /* @__PURE__ */ jsx(
@@ -3216,6 +3336,7 @@ function LeadGenListDetailPage({ listId }) {
3216
3336
  /* @__PURE__ */ jsx(Tabs.Panel, { value: "build", pt: "sm", children: /* @__PURE__ */ jsx(
3217
3337
  BuildTab,
3218
3338
  {
3339
+ list,
3219
3340
  steps: buildSteps,
3220
3341
  recommendedStep: recommendedBuildStep,
3221
3342
  onRunStep: openStepRun,
@@ -3302,13 +3423,14 @@ function LeadGenListDetailPage({ listId }) {
3302
3423
  opened: runModalOpen,
3303
3424
  onClose: closeRunModal,
3304
3425
  list,
3305
- actions,
3426
+ actions: runModalActions,
3306
3427
  selection: EMPTY_SELECTION2,
3307
3428
  initialResourceId: initialRunResourceId,
3308
3429
  title: "Run build step",
3309
3430
  description: "Run the selected bounded build workflow for this list.",
3310
3431
  lockResourceSelection: true,
3311
- onSubmitted: (_resourceId, executionId) => {
3432
+ onSubmitted: (resourceId, executionId) => {
3433
+ persistSubmittedStepConfig(resourceId);
3312
3434
  showSuccessNotification(`Workflow run started: ${executionId}`);
3313
3435
  }
3314
3436
  }
@@ -3673,4 +3795,4 @@ function LeadGenContactsPage() {
3673
3795
  ] }) });
3674
3796
  }
3675
3797
 
3676
- export { CompanyCleanupForm, CompanyDetailModal, ContactDetailModal, EmailDiscoveryForm, EmailVerificationForm, LEAD_GEN_ITEMS, LEAD_GEN_ROUTE_LINKS, LeadGenCompaniesPage, LeadGenContactsPage, LeadGenListDetailPage, LeadGenListsPage, LeadGenOverviewPage, LeadGenRouteShell, LeadGenSidebar, LeadGenSidebarMiddle, LeadGenSidebarTop, ListBuilderIndexPage, ListBuilderPage, RunWorkflowModal, WebsiteExtractForm, formatDate, getEnrichmentColor, getEnrichmentStatus, getStateKeyColor, getStatusColor, leadGenManifest, useDeleteLists };
3798
+ export { CompanyCleanupForm, CompanyDetailModal, ContactDetailModal, EmailDiscoveryForm, EmailVerificationForm, LEAD_GEN_ITEMS, LEAD_GEN_ROUTE_LINKS, LeadGenCompaniesPage, LeadGenContactsPage, LeadGenListDetailPage, LeadGenListsPage, LeadGenOverviewPage, LeadGenRouteShell, LeadGenSidebar, LeadGenSidebarMiddle, LeadGenSidebarTop, ListBuilderIndexPage, ListBuilderPage, RunWorkflowModal, TabSection, WebsiteExtractForm, formatDate, getEnrichmentColor, getEnrichmentStatus, getStateKeyColor, getStatusColor, leadGenManifest, useDeleteLists };