@elevasis/ui 2.25.5 → 2.26.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.
Files changed (101) hide show
  1. package/dist/api/index.js +2 -2
  2. package/dist/app/index.css +18 -29
  3. package/dist/app/index.d.ts +118 -64
  4. package/dist/app/index.js +6 -5
  5. package/dist/charts/index.js +6 -5
  6. package/dist/chunk-3MEXPLWT.js +265 -0
  7. package/dist/{chunk-IS53MXE4.js → chunk-4KTLOK7K.js} +1 -1
  8. package/dist/{chunk-KMAXFJPH.js → chunk-CW3UNAF2.js} +5 -409
  9. package/dist/{chunk-HKBEURCV.js → chunk-G26INIF3.js} +1 -1
  10. package/dist/{chunk-NHHCUECV.js → chunk-G66QFZXD.js} +11 -214
  11. package/dist/{chunk-QIW6OCEI.js → chunk-HLFFKKT3.js} +27 -373
  12. package/dist/chunk-JDNEWB5F.js +10 -0
  13. package/dist/{chunk-VMAWXEVG.js → chunk-JKBGDFX2.js} +1136 -828
  14. package/dist/{chunk-MU4VPAMR.js → chunk-JPGX3533.js} +4 -3
  15. package/dist/chunk-KCGGA36K.js +73 -0
  16. package/dist/chunk-KEFWANZY.js +155 -0
  17. package/dist/chunk-LH4GPYDX.js +448 -0
  18. package/dist/{chunk-QNCVK3ZF.js → chunk-LWKZ3BCC.js} +5 -4
  19. package/dist/chunk-OGXKOMUT.js +412 -0
  20. package/dist/chunk-OHXU5WWK.js +3731 -0
  21. package/dist/chunk-ONFKASZI.js +2004 -0
  22. package/dist/{chunk-U36X6NZM.js → chunk-RIFTUOPE.js} +2 -14
  23. package/dist/{chunk-T6INEVX6.js → chunk-SGS4CQ2B.js} +1 -1
  24. package/dist/{chunk-KINQW4JT.js → chunk-UPMX5GJI.js} +5 -5
  25. package/dist/{chunk-N2AP4I5N.js → chunk-UY5I2KOZ.js} +223 -3857
  26. package/dist/{chunk-JMI7L7Y7.js → chunk-W2ZTLH7Y.js} +142 -4
  27. package/dist/{chunk-3KY2GNPE.js → chunk-WUVR4QY6.js} +9 -9
  28. package/dist/{chunk-Q5BEODAT.js → chunk-X2SUMO3P.js} +2 -1
  29. package/dist/{chunk-SNHGSCKH.js → chunk-XBMCDGHA.js} +1 -1
  30. package/dist/{chunk-N55DVMAG.js → chunk-XQQEKWTL.js} +2 -6
  31. package/dist/{chunk-F7JDHS2I.js → chunk-XZSEPJZQ.js} +5 -5
  32. package/dist/{chunk-5BJXMZN4.js → chunk-YHBPR67D.js} +438 -620
  33. package/dist/{chunk-FVKLHLF4.js → chunk-YO2YORW4.js} +4 -4
  34. package/dist/{chunk-TAIX4NO3.js → chunk-ZFLM2YVW.js} +2 -2
  35. package/dist/components/index.css +18 -29
  36. package/dist/components/index.d.ts +211 -383
  37. package/dist/components/index.js +43 -427
  38. package/dist/components/navigation/index.css +28 -39
  39. package/dist/execution/index.d.ts +0 -73
  40. package/dist/features/auth/index.css +28 -39
  41. package/dist/features/crm/index.css +28 -39
  42. package/dist/features/crm/index.d.ts +49 -49
  43. package/dist/features/crm/index.js +14 -14
  44. package/dist/features/dashboard/index.css +28 -39
  45. package/dist/features/dashboard/index.js +18 -15
  46. package/dist/features/delivery/index.css +18 -29
  47. package/dist/features/delivery/index.js +14 -14
  48. package/dist/features/knowledge/index.css +611 -0
  49. package/dist/features/knowledge/index.js +700 -1
  50. package/dist/features/lead-gen/index.css +28 -39
  51. package/dist/features/lead-gen/index.d.ts +212 -166
  52. package/dist/features/lead-gen/index.js +16 -15
  53. package/dist/features/monitoring/index.css +18 -29
  54. package/dist/features/monitoring/index.js +17 -16
  55. package/dist/features/monitoring/requests/index.css +28 -39
  56. package/dist/features/monitoring/requests/index.js +13 -13
  57. package/dist/features/operations/index.css +28 -39
  58. package/dist/features/operations/index.d.ts +16 -98
  59. package/dist/features/operations/index.js +26 -20
  60. package/dist/features/settings/index.css +28 -39
  61. package/dist/features/settings/index.d.ts +1 -0
  62. package/dist/features/settings/index.js +15 -15
  63. package/dist/hooks/delivery/index.css +28 -39
  64. package/dist/hooks/delivery/index.js +2 -2
  65. package/dist/hooks/index.css +18 -29
  66. package/dist/hooks/index.d.ts +180 -377
  67. package/dist/hooks/index.js +13 -13
  68. package/dist/hooks/published.css +18 -29
  69. package/dist/hooks/published.d.ts +180 -377
  70. package/dist/hooks/published.js +13 -13
  71. package/dist/index.css +18 -29
  72. package/dist/index.d.ts +1549 -946
  73. package/dist/index.js +15 -14
  74. package/dist/initialization/index.d.ts +1 -0
  75. package/dist/knowledge/index.d.ts +991 -41
  76. package/dist/knowledge/index.js +5469 -413
  77. package/dist/layout/index.d.ts +2 -0
  78. package/dist/layout/index.js +3 -2
  79. package/dist/organization/index.css +28 -39
  80. package/dist/organization/index.d.ts +1 -0
  81. package/dist/provider/index.css +28 -39
  82. package/dist/provider/index.d.ts +1147 -348
  83. package/dist/provider/index.js +11 -10
  84. package/dist/provider/published.css +28 -39
  85. package/dist/provider/published.d.ts +1146 -347
  86. package/dist/provider/published.js +8 -8
  87. package/dist/test-utils/index.js +2 -2
  88. package/dist/test-utils/setup.js +1 -1
  89. package/dist/theme/index.js +3 -2
  90. package/dist/theme/presets/index.d.ts +97 -0
  91. package/dist/theme/presets/index.js +3 -0
  92. package/dist/types/index.d.ts +71 -126
  93. package/dist/utils/index.js +1 -1
  94. package/dist/vite/index.d.ts +7 -0
  95. package/dist/vite/index.js +10 -0
  96. package/dist/vite-plugin-knowledge/index.d.ts +1 -33
  97. package/dist/vite-plugin-knowledge/index.js +1 -66
  98. package/package.json +46 -33
  99. package/src/knowledge/README.md +8 -8
  100. package/src/theme/presets/README.md +19 -0
  101. /package/dist/{chunk-SGXXJE52.js → chunk-QD4X4H5A.js} +0 -0
@@ -1,11 +1,10 @@
1
1
  import { observabilityKeys } from './chunk-VKMNWHTL.js';
2
- import { showApiErrorNotification, showSuccessNotification, projectKeys, noteKeys, taskKeys, milestoneKeys } from './chunk-HKBEURCV.js';
2
+ import { showApiErrorNotification, showSuccessNotification, projectKeys, noteKeys, taskKeys, milestoneKeys } from './chunk-G26INIF3.js';
3
3
  import { useSupabase } from './chunk-BRXELOHC.js';
4
- import { GRAPH_CONSTANTS } from './chunk-22UVE3RA.js';
5
- import { useNotificationAdapter, deriveActions } from './chunk-JMI7L7Y7.js';
4
+ import { useNotificationAdapter, deriveActions } from './chunk-W2ZTLH7Y.js';
6
5
  import { useOptionalElevasisFeatures } from './chunk-V3HUIZJX.js';
7
- import { HTTP_HEADERS } from './chunk-T6INEVX6.js';
8
- import { ResourceTypeSchema, NonEmptyStringSchema, OriginResourceTypeSchema, UuidSchema, CredentialNameSchema, STALE_TIME_DEFAULT, REFETCH_INTERVAL_DASHBOARD, STALE_TIME_MONITORING, STALE_TIME_ADMIN, getTimeRangeDates, REFETCH_INTERVAL_RUNNING, WS_MAX_RETRIES_BEFORE_ERROR, WS_RECONNECT_BASE_DELAY, WS_RECONNECT_MAX_DELAY, APIClientError, GC_TIME_MEDIUM, GC_TIME_SHORT } from './chunk-SGXXJE52.js';
6
+ import { HTTP_HEADERS } from './chunk-SGS4CQ2B.js';
7
+ import { ResourceTypeSchema, NonEmptyStringSchema, OriginResourceTypeSchema, UuidSchema, CredentialNameSchema, STALE_TIME_DEFAULT, REFETCH_INTERVAL_DASHBOARD, STALE_TIME_MONITORING, getTimeRangeDates, REFETCH_INTERVAL_RUNNING, WS_MAX_RETRIES_BEFORE_ERROR, WS_RECONNECT_BASE_DELAY, WS_RECONNECT_MAX_DELAY, STALE_TIME_ADMIN, APIClientError, GC_TIME_MEDIUM, GC_TIME_SHORT } from './chunk-QD4X4H5A.js';
9
8
  import { useStableAccessToken } from './chunk-WFTNY755.js';
10
9
  import { useInitialization } from './chunk-WKJ47GIW.js';
11
10
  import { useOrganization } from './chunk-DD3CCMCZ.js';
@@ -17,7 +16,6 @@ import { z } from 'zod';
17
16
  import { notifications } from '@mantine/notifications';
18
17
  import { create } from 'zustand';
19
18
  import { persist } from 'zustand/middleware';
20
- import dagre from '@dagrejs/dagre';
21
19
  import { useNavigate, useSearch } from '@tanstack/react-router';
22
20
 
23
21
  // ../core/src/auth/multi-tenancy/permissions.ts
@@ -1598,533 +1596,6 @@ function usePatchTask() {
1598
1596
  }
1599
1597
  });
1600
1598
  }
1601
- function useCommandViewData() {
1602
- const { apiRequest, organizationId, isReady } = useElevasisServices();
1603
- return useQuery({
1604
- queryKey: ["command-view", organizationId],
1605
- queryFn: async () => {
1606
- return apiRequest("/command-view");
1607
- },
1608
- enabled: isReady,
1609
- staleTime: STALE_TIME_DEFAULT
1610
- });
1611
- }
1612
- function useCommandViewStats(timeRange = "30d", options) {
1613
- const { apiRequest, organizationId, isReady } = useElevasisServices();
1614
- return useQuery({
1615
- queryKey: ["command-view-stats", organizationId, timeRange],
1616
- queryFn: async () => {
1617
- return apiRequest(`/command-view/stats?timeRange=${timeRange}`);
1618
- },
1619
- enabled: isReady && (options?.enabled ?? true),
1620
- staleTime: STALE_TIME_MONITORING
1621
- });
1622
- }
1623
-
1624
- // src/features/operations/organization-graph/commandViewVisualizationModes.ts
1625
- var COMMAND_VIEW_VISUALIZATION_MODES = [
1626
- { label: "Cluster", value: "cluster" },
1627
- { label: "Swimlane", value: "swimlane" },
1628
- { label: "Focus", value: "focus" },
1629
- { label: "Network", value: "network" }
1630
- ];
1631
- var DEFAULT_COMMAND_VIEW_VISUALIZATION_MODE = "network";
1632
- var DOMAIN_ORDER = [
1633
- "operations",
1634
- "runtime",
1635
- "business",
1636
- "delivery",
1637
- "admin",
1638
- "system",
1639
- "platform",
1640
- "other"
1641
- ];
1642
- var DOMAIN_KEYWORDS = {
1643
- operations: [
1644
- "operation",
1645
- "command",
1646
- "queue",
1647
- "scheduler",
1648
- "resource",
1649
- "agent",
1650
- "workflow",
1651
- "checkpoint",
1652
- "organization graph"
1653
- ],
1654
- runtime: ["execution", "runner", "log", "session", "deploy", "webhook", "api key", "credential", "activity"],
1655
- business: ["sales", "crm", "lead", "seo", "analytics", "cost", "account"],
1656
- delivery: ["project", "task", "submission", "request", "design"],
1657
- admin: ["admin", "user", "organization", "notification", "archive"],
1658
- system: ["setting", "appearance", "debug", "monitoring", "health"],
1659
- platform: ["surface", "capability", "entity", "feature"],
1660
- other: []
1661
- };
1662
- function spread(index, count, spacing) {
1663
- return (index - (count - 1) / 2) * spacing;
1664
- }
1665
- function getNodeSortValue(node) {
1666
- return `${node.kind}:${node.label}:${node.id}`;
1667
- }
1668
- function getNodeDomain(node) {
1669
- if (node.kind === "organization") {
1670
- return "platform";
1671
- }
1672
- if (node.kind !== "feature" && node.kind !== "resource") {
1673
- return "platform";
1674
- }
1675
- const searchable = `${node.id} ${node.sourceId ?? ""} ${node.featureId ?? ""} ${node.resourceType ?? ""} ${node.label}`.toLowerCase();
1676
- for (const domain of DOMAIN_ORDER) {
1677
- if (domain === "other") {
1678
- continue;
1679
- }
1680
- if (DOMAIN_KEYWORDS[domain].some((keyword) => searchable.includes(keyword))) {
1681
- return domain;
1682
- }
1683
- }
1684
- return "other";
1685
- }
1686
- function groupNodesByDomain(graph) {
1687
- const groups = /* @__PURE__ */ new Map();
1688
- for (const domain of DOMAIN_ORDER) {
1689
- groups.set(domain, []);
1690
- }
1691
- for (const node of graph.nodes) {
1692
- groups.get(getNodeDomain(node))?.push(node);
1693
- }
1694
- for (const nodes of groups.values()) {
1695
- nodes.sort((left, right) => getNodeSortValue(left).localeCompare(getNodeSortValue(right)));
1696
- }
1697
- return groups;
1698
- }
1699
- function getNodeDegree(graph, nodeId) {
1700
- return graph.edges.filter((edge) => edge.sourceId === nodeId || edge.targetId === nodeId).length;
1701
- }
1702
- function getNeighbors(graph, nodeId) {
1703
- const neighbors = /* @__PURE__ */ new Set();
1704
- for (const edge of graph.edges) {
1705
- if (edge.sourceId === nodeId) {
1706
- neighbors.add(edge.targetId);
1707
- } else if (edge.targetId === nodeId) {
1708
- neighbors.add(edge.sourceId);
1709
- }
1710
- }
1711
- return neighbors;
1712
- }
1713
- function getClusterGraphPositions(graph) {
1714
- const positions = /* @__PURE__ */ new Map();
1715
- const groups = groupNodesByDomain(graph);
1716
- const zoneConfig = {
1717
- operations: { x: -520, y: -270, columns: 3, xGap: 188, yGap: 86 },
1718
- runtime: { x: 130, y: -270, columns: 3, xGap: 188, yGap: 86 },
1719
- business: { x: -520, y: 95, columns: 3, xGap: 188, yGap: 86 },
1720
- delivery: { x: 130, y: 95, columns: 3, xGap: 188, yGap: 86 },
1721
- admin: { x: -520, y: 420, columns: 3, xGap: 188, yGap: 86 },
1722
- system: { x: 130, y: 420, columns: 3, xGap: 188, yGap: 86 },
1723
- platform: { x: 0, y: -520, columns: 4, xGap: 205, yGap: 90 },
1724
- other: { x: 0, y: 710, columns: 6, xGap: 176, yGap: 78 }
1725
- };
1726
- for (const domain of DOMAIN_ORDER) {
1727
- const nodes = groups.get(domain) ?? [];
1728
- const zone = zoneConfig[domain];
1729
- for (const [index, node] of nodes.entries()) {
1730
- const row = Math.floor(index / zone.columns);
1731
- const column = index % zone.columns;
1732
- const rowCount = Math.min(zone.columns, nodes.length - row * zone.columns);
1733
- positions.set(node.id, {
1734
- x: zone.x + spread(column, rowCount, zone.xGap),
1735
- y: zone.y + row * zone.yGap
1736
- });
1737
- }
1738
- }
1739
- return positions;
1740
- }
1741
- function getSwimlaneGraphPositions(graph) {
1742
- const positions = /* @__PURE__ */ new Map();
1743
- const groups = groupNodesByDomain(graph);
1744
- const laneY = {
1745
- platform: -360,
1746
- operations: -220,
1747
- runtime: -80,
1748
- business: 60,
1749
- delivery: 200,
1750
- admin: 340,
1751
- system: 480,
1752
- other: 620
1753
- };
1754
- for (const domain of DOMAIN_ORDER) {
1755
- const nodes = groups.get(domain) ?? [];
1756
- const columns = Math.min(8, Math.max(1, Math.ceil(Math.sqrt(nodes.length) * 1.6)));
1757
- for (const [index, node] of nodes.entries()) {
1758
- const column = index % columns;
1759
- const row = Math.floor(index / columns);
1760
- const rowCount = Math.min(columns, nodes.length - row * columns);
1761
- positions.set(node.id, {
1762
- x: spread(column, rowCount, 178),
1763
- y: laneY[domain] + row * 74
1764
- });
1765
- }
1766
- }
1767
- return positions;
1768
- }
1769
- function getFocusGraphPositions(graph, selectedNodeId) {
1770
- if (!selectedNodeId || !graph.nodes.some((node) => node.id === selectedNodeId)) {
1771
- return getNetworkGraphPositions(graph);
1772
- }
1773
- const positions = /* @__PURE__ */ new Map();
1774
- const firstDegree = getNeighbors(graph, selectedNodeId);
1775
- const secondDegree = /* @__PURE__ */ new Set();
1776
- for (const nodeId of firstDegree) {
1777
- for (const neighborId of getNeighbors(graph, nodeId)) {
1778
- if (neighborId !== selectedNodeId && !firstDegree.has(neighborId)) {
1779
- secondDegree.add(neighborId);
1780
- }
1781
- }
1782
- }
1783
- positions.set(selectedNodeId, { x: 0, y: 0 });
1784
- const placeRing = (ids, radiusX, radiusY, yOffset = 0) => {
1785
- ids.forEach((id, index) => {
1786
- const angle = -Math.PI / 2 + index / Math.max(1, ids.length) * Math.PI * 2;
1787
- positions.set(id, {
1788
- x: Math.cos(angle) * radiusX,
1789
- y: yOffset + Math.sin(angle) * radiusY
1790
- });
1791
- });
1792
- };
1793
- placeRing([...firstDegree].sort(), 390, 210);
1794
- placeRing([...secondDegree].sort(), 680, 360);
1795
- const remaining = graph.nodes.filter((node) => !positions.has(node.id)).sort((left, right) => left.label.localeCompare(right.label));
1796
- for (const [index, node] of remaining.entries()) {
1797
- const column = index % 8;
1798
- const row = Math.floor(index / 8);
1799
- positions.set(node.id, {
1800
- x: spread(column, Math.min(8, remaining.length - row * 8), 160),
1801
- y: 560 + row * 78
1802
- });
1803
- }
1804
- return positions;
1805
- }
1806
- function getNetworkGraphPositions(graph) {
1807
- const positions = /* @__PURE__ */ new Map();
1808
- const nodes = [...graph.nodes].sort((left, right) => {
1809
- const degreeDelta = getNodeDegree(graph, right.id) - getNodeDegree(graph, left.id);
1810
- return degreeDelta || left.label.localeCompare(right.label);
1811
- });
1812
- for (const [index, node] of nodes.entries()) {
1813
- if (index === 0) {
1814
- positions.set(node.id, { x: 0, y: 0 });
1815
- continue;
1816
- }
1817
- const radius = 150 + Math.sqrt(index) * 82;
1818
- const angle = index * 2.399963229728653;
1819
- positions.set(node.id, {
1820
- x: Math.cos(angle) * radius,
1821
- y: Math.sin(angle) * radius * 0.72
1822
- });
1823
- }
1824
- return positions;
1825
- }
1826
- function getSpatialGraphPositions(graph) {
1827
- const positions = getSwimlaneGraphPositions(graph);
1828
- for (const [nodeId, position] of positions.entries()) {
1829
- const degree = getNodeDegree(graph, nodeId);
1830
- positions.set(nodeId, {
1831
- x: position.x + degree * 12,
1832
- y: position.y - degree * 8
1833
- });
1834
- }
1835
- return positions;
1836
- }
1837
- function getCommandViewGraphPositions({
1838
- graph,
1839
- visualizationMode,
1840
- selectedNodeId
1841
- }) {
1842
- switch (visualizationMode) {
1843
- case "swimlane":
1844
- return getSwimlaneGraphPositions(graph);
1845
- case "focus":
1846
- return getFocusGraphPositions(graph, selectedNodeId);
1847
- case "network":
1848
- return getNetworkGraphPositions(graph);
1849
- case "spatial":
1850
- return getSpatialGraphPositions(graph);
1851
- case "cluster":
1852
- default:
1853
- return getClusterGraphPositions(graph);
1854
- }
1855
- }
1856
-
1857
- // src/hooks/operations/command-view/useCommandViewStore.ts
1858
- var DEFAULT_DIAGNOSTIC_CATEGORIES = ["diagnostic", "testing"];
1859
- var useCommandViewStore = create()(
1860
- persist(
1861
- (set) => ({
1862
- statusFilter: "all",
1863
- setStatusFilter: (statusFilter) => set({ statusFilter }),
1864
- showIntegrations: true,
1865
- setShowIntegrations: (showIntegrations) => set({ showIntegrations }),
1866
- fitViewOnFilter: true,
1867
- setFitViewOnFilter: (fitViewOnFilter) => set({ fitViewOnFilter }),
1868
- visualizationMode: DEFAULT_COMMAND_VIEW_VISUALIZATION_MODE,
1869
- setVisualizationMode: (visualizationMode) => set({ visualizationMode }),
1870
- selectedNodeId: null,
1871
- setSelectedNodeId: (selectedNodeId) => set({ selectedNodeId }),
1872
- resourcesHidden: true,
1873
- setResourcesHidden: (resourcesHidden) => set({ resourcesHidden, hasVisibilityInteraction: true }),
1874
- diagnosticsHidden: true,
1875
- setDiagnosticsHidden: (diagnosticsHidden) => set({ diagnosticsHidden, hasVisibilityInteraction: true }),
1876
- diagnosticCategories: DEFAULT_DIAGNOSTIC_CATEGORIES,
1877
- revealedIds: /* @__PURE__ */ new Set(),
1878
- setRevealedIds: (ids) => set({ revealedIds: new Set(ids) }),
1879
- clearRevealedIds: () => set({ revealedIds: /* @__PURE__ */ new Set() }),
1880
- hasVisibilityInteraction: false,
1881
- markVisibilityInteraction: () => set({ hasVisibilityInteraction: true }),
1882
- resetVisibilityInteraction: () => set({ hasVisibilityInteraction: false })
1883
- }),
1884
- {
1885
- name: "command-view-store",
1886
- partialize: (s) => ({
1887
- showIntegrations: s.showIntegrations,
1888
- fitViewOnFilter: s.fitViewOnFilter,
1889
- visualizationMode: s.visualizationMode,
1890
- resourcesHidden: s.resourcesHidden,
1891
- diagnosticsHidden: s.diagnosticsHidden
1892
- })
1893
- }
1894
- )
1895
- );
1896
- function useCommandViewLayout(graph) {
1897
- return useMemo(() => {
1898
- const dagreGraph = new dagre.graphlib.Graph();
1899
- dagreGraph.setDefaultEdgeLabel(() => ({}));
1900
- dagreGraph.setGraph({
1901
- rankdir: "LR",
1902
- ranksep: GRAPH_CONSTANTS.RANK_SEP,
1903
- nodesep: GRAPH_CONSTANTS.NODE_SEP,
1904
- marginx: 50,
1905
- marginy: 50,
1906
- ranker: "longest-path"
1907
- });
1908
- graph.nodes.forEach((node) => {
1909
- dagreGraph.setNode(node.id, {
1910
- width: GRAPH_CONSTANTS.NODE_WIDTH,
1911
- height: GRAPH_CONSTANTS.NODE_HEIGHT
1912
- });
1913
- });
1914
- graph.edges.forEach((edge) => {
1915
- dagreGraph.setEdge(edge.source, edge.target);
1916
- });
1917
- dagre.layout(dagreGraph);
1918
- const nodePositions = /* @__PURE__ */ new Map();
1919
- const nodeNames = /* @__PURE__ */ new Map();
1920
- graph.nodes.forEach((node) => {
1921
- const dagreNode = dagreGraph.node(node.id);
1922
- nodePositions.set(node.id, { x: dagreNode.x, y: dagreNode.y });
1923
- nodeNames.set(node.id, node.name);
1924
- });
1925
- const parent = /* @__PURE__ */ new Map();
1926
- graph.nodes.forEach((node) => parent.set(node.id, node.id));
1927
- const find = (id) => {
1928
- if (parent.get(id) !== id) {
1929
- parent.set(id, find(parent.get(id)));
1930
- }
1931
- return parent.get(id);
1932
- };
1933
- const union = (a, b) => {
1934
- const rootA = find(a);
1935
- const rootB = find(b);
1936
- if (rootA !== rootB) {
1937
- parent.set(rootA, rootB);
1938
- }
1939
- };
1940
- graph.edges.forEach((edge) => {
1941
- if (edge.relationship === "triggers" || edge.relationship === "approval") {
1942
- union(edge.source, edge.target);
1943
- }
1944
- });
1945
- const components = /* @__PURE__ */ new Map();
1946
- graph.nodes.forEach((node) => {
1947
- const root = find(node.id);
1948
- const existing = components.get(root) || [];
1949
- existing.push(node.id);
1950
- components.set(root, existing);
1951
- });
1952
- const getMinPrefix = (nodeIds) => {
1953
- let minPrefix = "";
1954
- for (const id of nodeIds) {
1955
- const name = nodeNames.get(id) || "";
1956
- const prefix = name.match(/^([A-Z]+-\d+)/)?.[1];
1957
- if (prefix && (!minPrefix || prefix.localeCompare(minPrefix) < 0)) {
1958
- minPrefix = prefix;
1959
- }
1960
- }
1961
- return minPrefix || nodeNames.get(nodeIds[0]) || "";
1962
- };
1963
- const sortedComponents = Array.from(components.values()).sort((a, b) => {
1964
- return getMinPrefix(a).localeCompare(getMinPrefix(b));
1965
- });
1966
- const chains = sortedComponents.filter((c) => c.length > 1);
1967
- const orphans = sortedComponents.filter((c) => c.length === 1);
1968
- const componentYOffsets = /* @__PURE__ */ new Map();
1969
- let currentY = 0;
1970
- for (const nodeIds of chains) {
1971
- let minY = Infinity;
1972
- let maxY = -Infinity;
1973
- for (const id of nodeIds) {
1974
- const pos = nodePositions.get(id);
1975
- minY = Math.min(minY, pos.y);
1976
- maxY = Math.max(maxY, pos.y);
1977
- }
1978
- const offset = currentY - minY + 50;
1979
- for (const id of nodeIds) {
1980
- componentYOffsets.set(id, offset);
1981
- }
1982
- currentY = currentY + (maxY - minY) + GRAPH_CONSTANTS.NODE_HEIGHT + 80;
1983
- }
1984
- if (orphans.length > 0) {
1985
- const longestChainDepth = chains.length > 0 ? Math.max(
1986
- ...chains.map((chain) => {
1987
- const xValues = new Set(chain.map((id) => Math.round(nodePositions.get(id).x)));
1988
- return xValues.size;
1989
- })
1990
- ) : 0;
1991
- const ORPHAN_COLS = Math.max(5, longestChainDepth + Math.floor(longestChainDepth / 4));
1992
- const cellW = GRAPH_CONSTANTS.NODE_WIDTH + GRAPH_CONSTANTS.NODE_SEP;
1993
- const cellH = GRAPH_CONSTANTS.NODE_HEIGHT + GRAPH_CONSTANTS.NODE_SEP;
1994
- const gridStartY = currentY + 50;
1995
- orphans.forEach((nodeIds, i) => {
1996
- const id = nodeIds[0];
1997
- const col = i % ORPHAN_COLS;
1998
- const row = Math.floor(i / ORPHAN_COLS);
1999
- nodePositions.set(id, {
2000
- x: col * cellW + GRAPH_CONSTANTS.NODE_WIDTH / 2,
2001
- y: gridStartY + row * cellH + GRAPH_CONSTANTS.NODE_HEIGHT / 2
2002
- });
2003
- componentYOffsets.set(id, 0);
2004
- });
2005
- }
2006
- const nodes = graph.nodes.map((node) => {
2007
- const pos = nodePositions.get(node.id);
2008
- const yOffset = componentYOffsets.get(node.id) || 0;
2009
- return {
2010
- id: node.id,
2011
- type: "commandView",
2012
- position: {
2013
- x: pos.x - GRAPH_CONSTANTS.NODE_WIDTH / 2,
2014
- y: pos.y + yOffset - GRAPH_CONSTANTS.NODE_HEIGHT / 2
2015
- },
2016
- data: node
2017
- };
2018
- });
2019
- const edgesBySource = /* @__PURE__ */ new Map();
2020
- graph.edges.forEach((edge) => {
2021
- const existing = edgesBySource.get(edge.source) || [];
2022
- existing.push(edge);
2023
- edgesBySource.set(edge.source, existing);
2024
- });
2025
- const edges = graph.edges.map((edge) => {
2026
- const sourceEdges = edgesBySource.get(edge.source) || [];
2027
- const edgeIndex = sourceEdges.indexOf(edge);
2028
- const totalEdges = sourceEdges.length;
2029
- return {
2030
- id: edge.id,
2031
- source: edge.source,
2032
- target: edge.target,
2033
- type: "commandView",
2034
- data: {
2035
- relationship: edge.relationship,
2036
- label: edge.label,
2037
- edgeIndex,
2038
- totalEdges
2039
- }
2040
- };
2041
- });
2042
- return { nodes, edges };
2043
- }, [graph]);
2044
- }
2045
- function useGraphStats(graph) {
2046
- return useMemo(() => {
2047
- const stats = {
2048
- agents: 0,
2049
- workflows: 0,
2050
- integrations: 0,
2051
- triggers: 0,
2052
- prodResources: 0,
2053
- devResources: 0,
2054
- connectedIntegrations: 0,
2055
- errorIntegrations: 0
2056
- };
2057
- for (const node of graph.nodes) {
2058
- switch (node.type) {
2059
- case "agent":
2060
- stats.agents++;
2061
- break;
2062
- case "workflow":
2063
- stats.workflows++;
2064
- break;
2065
- case "integration":
2066
- stats.integrations++;
2067
- if (node.connectionStatus === "connected") stats.connectedIntegrations++;
2068
- if (node.connectionStatus === "error") stats.errorIntegrations++;
2069
- break;
2070
- case "trigger":
2071
- stats.triggers++;
2072
- break;
2073
- }
2074
- if (node.status === "prod") stats.prodResources++;
2075
- if (node.status === "dev") stats.devResources++;
2076
- }
2077
- return stats;
2078
- }, [graph]);
2079
- }
2080
- function useCheckpointTasks({ checkpointId, enabled = true }) {
2081
- const { apiRequest, organizationId, isReady } = useElevasisServices();
2082
- return useQuery({
2083
- queryKey: ["checkpoint-tasks", organizationId, checkpointId],
2084
- queryFn: async () => {
2085
- return apiRequest(
2086
- `/command-queue?humanCheckpoint=${checkpointId}&status=pending&limit=10`
2087
- );
2088
- },
2089
- // Only fetch when: org ready, checkpoint selected, and enabled
2090
- enabled: isReady && !!checkpointId && enabled,
2091
- staleTime: STALE_TIME_MONITORING
2092
- });
2093
- }
2094
- function useResourceErrors({ resourceId, timeRange, hasFailures }) {
2095
- const { apiRequest, organizationId, isReady } = useElevasisServices();
2096
- return useQuery({
2097
- queryKey: ["resource-errors", organizationId, resourceId, timeRange],
2098
- queryFn: async () => {
2099
- return apiRequest(
2100
- `/command-view/resource-errors?resourceId=${resourceId}&timeRange=${timeRange}`
2101
- );
2102
- },
2103
- // Only fetch when: org ready, resource selected, and resource has failures
2104
- enabled: isReady && !!resourceId && hasFailures,
2105
- staleTime: STALE_TIME_ADMIN
2106
- });
2107
- }
2108
- function useResourceExecutions({
2109
- resourceId,
2110
- timeRange,
2111
- page = 1,
2112
- limit = 10,
2113
- enabled = true
2114
- }) {
2115
- const { apiRequest, organizationId, isReady } = useElevasisServices();
2116
- return useQuery({
2117
- queryKey: ["resource-executions", organizationId, resourceId, timeRange, page, limit],
2118
- queryFn: async () => {
2119
- return apiRequest(
2120
- `/command-view/resource-executions?resourceId=${resourceId}&timeRange=${timeRange}&page=${page}&limit=${limit}`
2121
- );
2122
- },
2123
- // Only fetch when: org ready, resource selected, and enabled
2124
- enabled: isReady && !!resourceId && enabled,
2125
- staleTime: STALE_TIME_MONITORING
2126
- });
2127
- }
2128
1599
  var DEFAULT_DEALS_LIMIT = 50;
2129
1600
  var DEFAULT_DEALS_OFFSET = 0;
2130
1601
  var DEFAULT_LOOKUP_LIMIT = 10;
@@ -2661,98 +2132,427 @@ function useTransitionListMember() {
2661
2132
  queryClient.invalidateQueries({ queryKey: leadGenListMemberKeys.all });
2662
2133
  showApiErrorNotification(error);
2663
2134
  }
2664
- });
2135
+ });
2136
+ }
2137
+ var leadGenListCompanyKeys = {
2138
+ all: ["lead-gen-list-companies"],
2139
+ detail: (organizationId, listCompanyId) => [...leadGenListCompanyKeys.all, organizationId, "detail", listCompanyId]
2140
+ };
2141
+ function useTransitionListCompany() {
2142
+ const { apiRequest, organizationId } = useElevasisServices();
2143
+ const queryClient = useQueryClient();
2144
+ return useMutation({
2145
+ mutationFn: async (input) => {
2146
+ const { listCompanyId, pipelineKey, stageKey, stateKey, reason, expectedUpdatedAt } = input;
2147
+ await apiRequest(`/acquisition/list-companies/${listCompanyId}/transition`, {
2148
+ method: "PATCH",
2149
+ body: JSON.stringify({
2150
+ pipelineKey,
2151
+ stageKey,
2152
+ ...stateKey !== void 0 ? { stateKey } : {},
2153
+ ...reason !== void 0 ? { reason } : {},
2154
+ ...expectedUpdatedAt !== void 0 ? { expectedUpdatedAt } : {}
2155
+ })
2156
+ });
2157
+ },
2158
+ onSuccess: (_, variables) => {
2159
+ queryClient.invalidateQueries({
2160
+ queryKey: leadGenListCompanyKeys.detail(organizationId, variables.listCompanyId)
2161
+ });
2162
+ if (variables.listId) {
2163
+ queryClient.invalidateQueries({ queryKey: acquisitionListKeys.telemetry(organizationId) });
2164
+ queryClient.invalidateQueries({ queryKey: acquisitionListKeys.detail(organizationId, variables.listId) });
2165
+ }
2166
+ },
2167
+ onError: (error) => {
2168
+ queryClient.invalidateQueries({ queryKey: leadGenListCompanyKeys.all });
2169
+ showApiErrorNotification(error);
2170
+ }
2171
+ });
2172
+ }
2173
+ function useDeriveActions(item) {
2174
+ return useMemo(() => {
2175
+ if (!item) return [];
2176
+ if (item.pipeline_key !== "lead-gen") {
2177
+ return deriveActions(item);
2178
+ }
2179
+ return [];
2180
+ }, [item]);
2181
+ }
2182
+ function useUpdateListStatus() {
2183
+ const { apiRequest, organizationId } = useElevasisServices();
2184
+ const queryClient = useQueryClient();
2185
+ return useMutation({
2186
+ mutationFn: async (input) => {
2187
+ await apiRequest(`/acquisition/lists/${input.listId}/status`, {
2188
+ method: "PATCH",
2189
+ body: JSON.stringify({ status: input.status })
2190
+ });
2191
+ },
2192
+ onSuccess: (_, variables) => {
2193
+ queryClient.invalidateQueries({ queryKey: acquisitionListKeys.list(organizationId) });
2194
+ queryClient.invalidateQueries({ queryKey: acquisitionListKeys.detail(organizationId, variables.listId) });
2195
+ queryClient.invalidateQueries({ queryKey: acquisitionListKeys.telemetry(organizationId) });
2196
+ },
2197
+ onError: (error) => {
2198
+ queryClient.invalidateQueries({ queryKey: acquisitionListKeys.all });
2199
+ showApiErrorNotification(error);
2200
+ }
2201
+ });
2202
+ }
2203
+ var projectActivityKeys = {
2204
+ all: ["project-activities"],
2205
+ list: (projectId) => [...projectActivityKeys.all, "list", projectId]
2206
+ };
2207
+ function useProjectActivities(projectId, enabled = true) {
2208
+ const { apiRequest, isReady, organizationId } = useElevasisServices();
2209
+ return useQuery({
2210
+ queryKey: [...projectActivityKeys.list(projectId), organizationId],
2211
+ queryFn: async () => {
2212
+ const params = new URLSearchParams();
2213
+ params.set("entityType", "project");
2214
+ params.set("entityId", projectId);
2215
+ params.set("limit", "50");
2216
+ const res = await apiRequest(`/activities?${params.toString()}`);
2217
+ return res.activities.map((activity) => ({
2218
+ ...activity,
2219
+ occurredAt: new Date(activity.occurredAt),
2220
+ createdAt: new Date(activity.createdAt)
2221
+ }));
2222
+ },
2223
+ enabled: isReady && !!projectId && enabled
2224
+ });
2225
+ }
2226
+ function useCommandViewData() {
2227
+ const { apiRequest, organizationId, isReady } = useElevasisServices();
2228
+ return useQuery({
2229
+ queryKey: ["command-view", organizationId],
2230
+ queryFn: async () => {
2231
+ return apiRequest("/command-view");
2232
+ },
2233
+ enabled: isReady,
2234
+ staleTime: STALE_TIME_DEFAULT
2235
+ });
2236
+ }
2237
+ function useCommandViewStats(timeRange = "30d", options) {
2238
+ const { apiRequest, organizationId, isReady } = useElevasisServices();
2239
+ return useQuery({
2240
+ queryKey: ["command-view-stats", organizationId, timeRange],
2241
+ queryFn: async () => {
2242
+ return apiRequest(`/command-view/stats?timeRange=${timeRange}`);
2243
+ },
2244
+ enabled: isReady && (options?.enabled ?? true),
2245
+ staleTime: STALE_TIME_MONITORING
2246
+ });
2247
+ }
2248
+ function useCheckpointTasks({ checkpointId, enabled = true }) {
2249
+ const { apiRequest, organizationId, isReady } = useElevasisServices();
2250
+ return useQuery({
2251
+ queryKey: ["checkpoint-tasks", organizationId, checkpointId],
2252
+ queryFn: async () => {
2253
+ return apiRequest(
2254
+ `/command-queue?humanCheckpoint=${checkpointId}&status=pending&limit=10`
2255
+ );
2256
+ },
2257
+ // Only fetch when: org ready, checkpoint selected, and enabled
2258
+ enabled: isReady && !!checkpointId && enabled,
2259
+ staleTime: STALE_TIME_MONITORING
2260
+ });
2261
+ }
2262
+ function useResourceExecutions({
2263
+ resourceId,
2264
+ timeRange,
2265
+ page = 1,
2266
+ limit = 10,
2267
+ enabled = true
2268
+ }) {
2269
+ const { apiRequest, organizationId, isReady } = useElevasisServices();
2270
+ return useQuery({
2271
+ queryKey: ["resource-executions", organizationId, resourceId, timeRange, page, limit],
2272
+ queryFn: async () => {
2273
+ return apiRequest(
2274
+ `/command-view/resource-executions?resourceId=${resourceId}&timeRange=${timeRange}&page=${page}&limit=${limit}`
2275
+ );
2276
+ },
2277
+ // Only fetch when: org ready, resource selected, and enabled
2278
+ enabled: isReady && !!resourceId && enabled,
2279
+ staleTime: STALE_TIME_MONITORING
2280
+ });
2281
+ }
2282
+
2283
+ // src/features/operations/organization-graph/commandViewVisualizationModes.ts
2284
+ var COMMAND_VIEW_VISUALIZATION_MODES = [
2285
+ { label: "Cluster", value: "cluster" },
2286
+ { label: "Swimlane", value: "swimlane" },
2287
+ { label: "Focus", value: "focus" },
2288
+ { label: "Network", value: "network" }
2289
+ ];
2290
+ var DEFAULT_COMMAND_VIEW_VISUALIZATION_MODE = "network";
2291
+ var DOMAIN_ORDER = [
2292
+ "operations",
2293
+ "runtime",
2294
+ "business",
2295
+ "delivery",
2296
+ "admin",
2297
+ "system",
2298
+ "platform",
2299
+ "other"
2300
+ ];
2301
+ var DOMAIN_KEYWORDS = {
2302
+ operations: [
2303
+ "operation",
2304
+ "command",
2305
+ "queue",
2306
+ "scheduler",
2307
+ "resource",
2308
+ "agent",
2309
+ "workflow",
2310
+ "checkpoint",
2311
+ "organization graph"
2312
+ ],
2313
+ runtime: ["execution", "runner", "log", "session", "deploy", "webhook", "api key", "credential", "activity"],
2314
+ business: ["sales", "crm", "lead", "seo", "analytics", "cost", "account"],
2315
+ delivery: ["project", "task", "submission", "request", "design"],
2316
+ admin: ["admin", "user", "organization", "notification", "archive"],
2317
+ system: ["setting", "appearance", "debug", "monitoring", "health"],
2318
+ platform: ["surface", "capability", "entity", "feature"],
2319
+ other: []
2320
+ };
2321
+ function spread(index, count, spacing) {
2322
+ return (index - (count - 1) / 2) * spacing;
2323
+ }
2324
+ function getNodeSortValue(node) {
2325
+ return `${node.kind}:${node.label}:${node.id}`;
2326
+ }
2327
+ function getNodeDomain(node) {
2328
+ if (node.kind === "organization") {
2329
+ return "platform";
2330
+ }
2331
+ if (node.kind !== "feature" && node.kind !== "resource") {
2332
+ return "platform";
2333
+ }
2334
+ const searchable = `${node.id} ${node.sourceId ?? ""} ${node.featureId ?? ""} ${node.resourceType ?? ""} ${node.label}`.toLowerCase();
2335
+ for (const domain of DOMAIN_ORDER) {
2336
+ if (domain === "other") {
2337
+ continue;
2338
+ }
2339
+ if (DOMAIN_KEYWORDS[domain].some((keyword) => searchable.includes(keyword))) {
2340
+ return domain;
2341
+ }
2342
+ }
2343
+ return "other";
2344
+ }
2345
+ function groupNodesByDomain(graph) {
2346
+ const groups = /* @__PURE__ */ new Map();
2347
+ for (const domain of DOMAIN_ORDER) {
2348
+ groups.set(domain, []);
2349
+ }
2350
+ for (const node of graph.nodes) {
2351
+ groups.get(getNodeDomain(node))?.push(node);
2352
+ }
2353
+ for (const nodes of groups.values()) {
2354
+ nodes.sort((left, right) => getNodeSortValue(left).localeCompare(getNodeSortValue(right)));
2355
+ }
2356
+ return groups;
2357
+ }
2358
+ function getNodeDegree(graph, nodeId) {
2359
+ return graph.edges.filter((edge) => edge.sourceId === nodeId || edge.targetId === nodeId).length;
2360
+ }
2361
+ function getNeighbors(graph, nodeId) {
2362
+ const neighbors = /* @__PURE__ */ new Set();
2363
+ for (const edge of graph.edges) {
2364
+ if (edge.sourceId === nodeId) {
2365
+ neighbors.add(edge.targetId);
2366
+ } else if (edge.targetId === nodeId) {
2367
+ neighbors.add(edge.sourceId);
2368
+ }
2369
+ }
2370
+ return neighbors;
2371
+ }
2372
+ function getClusterGraphPositions(graph) {
2373
+ const positions = /* @__PURE__ */ new Map();
2374
+ const groups = groupNodesByDomain(graph);
2375
+ const zoneConfig = {
2376
+ operations: { x: -520, y: -270, columns: 3, xGap: 188, yGap: 86 },
2377
+ runtime: { x: 130, y: -270, columns: 3, xGap: 188, yGap: 86 },
2378
+ business: { x: -520, y: 95, columns: 3, xGap: 188, yGap: 86 },
2379
+ delivery: { x: 130, y: 95, columns: 3, xGap: 188, yGap: 86 },
2380
+ admin: { x: -520, y: 420, columns: 3, xGap: 188, yGap: 86 },
2381
+ system: { x: 130, y: 420, columns: 3, xGap: 188, yGap: 86 },
2382
+ platform: { x: 0, y: -520, columns: 4, xGap: 205, yGap: 90 },
2383
+ other: { x: 0, y: 710, columns: 6, xGap: 176, yGap: 78 }
2384
+ };
2385
+ for (const domain of DOMAIN_ORDER) {
2386
+ const nodes = groups.get(domain) ?? [];
2387
+ const zone = zoneConfig[domain];
2388
+ for (const [index, node] of nodes.entries()) {
2389
+ const row = Math.floor(index / zone.columns);
2390
+ const column = index % zone.columns;
2391
+ const rowCount = Math.min(zone.columns, nodes.length - row * zone.columns);
2392
+ positions.set(node.id, {
2393
+ x: zone.x + spread(column, rowCount, zone.xGap),
2394
+ y: zone.y + row * zone.yGap
2395
+ });
2396
+ }
2397
+ }
2398
+ return positions;
2665
2399
  }
2666
- var leadGenListCompanyKeys = {
2667
- all: ["lead-gen-list-companies"],
2668
- detail: (organizationId, listCompanyId) => [...leadGenListCompanyKeys.all, organizationId, "detail", listCompanyId]
2669
- };
2670
- function useTransitionListCompany() {
2671
- const { apiRequest, organizationId } = useElevasisServices();
2672
- const queryClient = useQueryClient();
2673
- return useMutation({
2674
- mutationFn: async (input) => {
2675
- const { listCompanyId, pipelineKey, stageKey, stateKey, reason, expectedUpdatedAt } = input;
2676
- await apiRequest(`/acquisition/list-companies/${listCompanyId}/transition`, {
2677
- method: "PATCH",
2678
- body: JSON.stringify({
2679
- pipelineKey,
2680
- stageKey,
2681
- ...stateKey !== void 0 ? { stateKey } : {},
2682
- ...reason !== void 0 ? { reason } : {},
2683
- ...expectedUpdatedAt !== void 0 ? { expectedUpdatedAt } : {}
2684
- })
2685
- });
2686
- },
2687
- onSuccess: (_, variables) => {
2688
- queryClient.invalidateQueries({
2689
- queryKey: leadGenListCompanyKeys.detail(organizationId, variables.listCompanyId)
2400
+ function getSwimlaneGraphPositions(graph) {
2401
+ const positions = /* @__PURE__ */ new Map();
2402
+ const groups = groupNodesByDomain(graph);
2403
+ const laneY = {
2404
+ platform: -360,
2405
+ operations: -220,
2406
+ runtime: -80,
2407
+ business: 60,
2408
+ delivery: 200,
2409
+ admin: 340,
2410
+ system: 480,
2411
+ other: 620
2412
+ };
2413
+ for (const domain of DOMAIN_ORDER) {
2414
+ const nodes = groups.get(domain) ?? [];
2415
+ const columns = Math.min(8, Math.max(1, Math.ceil(Math.sqrt(nodes.length) * 1.6)));
2416
+ for (const [index, node] of nodes.entries()) {
2417
+ const column = index % columns;
2418
+ const row = Math.floor(index / columns);
2419
+ const rowCount = Math.min(columns, nodes.length - row * columns);
2420
+ positions.set(node.id, {
2421
+ x: spread(column, rowCount, 178),
2422
+ y: laneY[domain] + row * 74
2690
2423
  });
2691
- if (variables.listId) {
2692
- queryClient.invalidateQueries({ queryKey: acquisitionListKeys.telemetry(organizationId) });
2693
- queryClient.invalidateQueries({ queryKey: acquisitionListKeys.detail(organizationId, variables.listId) });
2694
- }
2695
- },
2696
- onError: (error) => {
2697
- queryClient.invalidateQueries({ queryKey: leadGenListCompanyKeys.all });
2698
- showApiErrorNotification(error);
2699
2424
  }
2700
- });
2425
+ }
2426
+ return positions;
2701
2427
  }
2702
- function useDeriveActions(item) {
2703
- return useMemo(() => {
2704
- if (!item) return [];
2705
- if (item.pipeline_key !== "lead-gen") {
2706
- return deriveActions(item);
2428
+ function getFocusGraphPositions(graph, selectedNodeId) {
2429
+ if (!selectedNodeId || !graph.nodes.some((node) => node.id === selectedNodeId)) {
2430
+ return getNetworkGraphPositions(graph);
2431
+ }
2432
+ const positions = /* @__PURE__ */ new Map();
2433
+ const firstDegree = getNeighbors(graph, selectedNodeId);
2434
+ const secondDegree = /* @__PURE__ */ new Set();
2435
+ for (const nodeId of firstDegree) {
2436
+ for (const neighborId of getNeighbors(graph, nodeId)) {
2437
+ if (neighborId !== selectedNodeId && !firstDegree.has(neighborId)) {
2438
+ secondDegree.add(neighborId);
2439
+ }
2707
2440
  }
2708
- return [];
2709
- }, [item]);
2710
- }
2711
- function useUpdateListStatus() {
2712
- const { apiRequest, organizationId } = useElevasisServices();
2713
- const queryClient = useQueryClient();
2714
- return useMutation({
2715
- mutationFn: async (input) => {
2716
- await apiRequest(`/acquisition/lists/${input.listId}/status`, {
2717
- method: "PATCH",
2718
- body: JSON.stringify({ status: input.status })
2441
+ }
2442
+ positions.set(selectedNodeId, { x: 0, y: 0 });
2443
+ const placeRing = (ids, radiusX, radiusY, yOffset = 0) => {
2444
+ ids.forEach((id, index) => {
2445
+ const angle = -Math.PI / 2 + index / Math.max(1, ids.length) * Math.PI * 2;
2446
+ positions.set(id, {
2447
+ x: Math.cos(angle) * radiusX,
2448
+ y: yOffset + Math.sin(angle) * radiusY
2719
2449
  });
2720
- },
2721
- onSuccess: (_, variables) => {
2722
- queryClient.invalidateQueries({ queryKey: acquisitionListKeys.list(organizationId) });
2723
- queryClient.invalidateQueries({ queryKey: acquisitionListKeys.detail(organizationId, variables.listId) });
2724
- queryClient.invalidateQueries({ queryKey: acquisitionListKeys.telemetry(organizationId) });
2725
- },
2726
- onError: (error) => {
2727
- queryClient.invalidateQueries({ queryKey: acquisitionListKeys.all });
2728
- showApiErrorNotification(error);
2729
- }
2730
- });
2450
+ });
2451
+ };
2452
+ placeRing([...firstDegree].sort(), 390, 210);
2453
+ placeRing([...secondDegree].sort(), 680, 360);
2454
+ const remaining = graph.nodes.filter((node) => !positions.has(node.id)).sort((left, right) => left.label.localeCompare(right.label));
2455
+ for (const [index, node] of remaining.entries()) {
2456
+ const column = index % 8;
2457
+ const row = Math.floor(index / 8);
2458
+ positions.set(node.id, {
2459
+ x: spread(column, Math.min(8, remaining.length - row * 8), 160),
2460
+ y: 560 + row * 78
2461
+ });
2462
+ }
2463
+ return positions;
2731
2464
  }
2732
- var projectActivityKeys = {
2733
- all: ["project-activities"],
2734
- list: (projectId) => [...projectActivityKeys.all, "list", projectId]
2735
- };
2736
- function useProjectActivities(projectId, enabled = true) {
2737
- const { apiRequest, isReady, organizationId } = useElevasisServices();
2738
- return useQuery({
2739
- queryKey: [...projectActivityKeys.list(projectId), organizationId],
2740
- queryFn: async () => {
2741
- const params = new URLSearchParams();
2742
- params.set("entityType", "project");
2743
- params.set("entityId", projectId);
2744
- params.set("limit", "50");
2745
- const res = await apiRequest(`/activities?${params.toString()}`);
2746
- return res.activities.map((activity) => ({
2747
- ...activity,
2748
- occurredAt: new Date(activity.occurredAt),
2749
- createdAt: new Date(activity.createdAt)
2750
- }));
2751
- },
2752
- enabled: isReady && !!projectId && enabled
2465
+ function getNetworkGraphPositions(graph) {
2466
+ const positions = /* @__PURE__ */ new Map();
2467
+ const nodes = [...graph.nodes].sort((left, right) => {
2468
+ const degreeDelta = getNodeDegree(graph, right.id) - getNodeDegree(graph, left.id);
2469
+ return degreeDelta || left.label.localeCompare(right.label);
2753
2470
  });
2471
+ for (const [index, node] of nodes.entries()) {
2472
+ if (index === 0) {
2473
+ positions.set(node.id, { x: 0, y: 0 });
2474
+ continue;
2475
+ }
2476
+ const radius = 150 + Math.sqrt(index) * 82;
2477
+ const angle = index * 2.399963229728653;
2478
+ positions.set(node.id, {
2479
+ x: Math.cos(angle) * radius,
2480
+ y: Math.sin(angle) * radius * 0.72
2481
+ });
2482
+ }
2483
+ return positions;
2484
+ }
2485
+ function getSpatialGraphPositions(graph) {
2486
+ const positions = getSwimlaneGraphPositions(graph);
2487
+ for (const [nodeId, position] of positions.entries()) {
2488
+ const degree = getNodeDegree(graph, nodeId);
2489
+ positions.set(nodeId, {
2490
+ x: position.x + degree * 12,
2491
+ y: position.y - degree * 8
2492
+ });
2493
+ }
2494
+ return positions;
2495
+ }
2496
+ function getCommandViewGraphPositions({
2497
+ graph,
2498
+ visualizationMode,
2499
+ selectedNodeId
2500
+ }) {
2501
+ switch (visualizationMode) {
2502
+ case "swimlane":
2503
+ return getSwimlaneGraphPositions(graph);
2504
+ case "focus":
2505
+ return getFocusGraphPositions(graph, selectedNodeId);
2506
+ case "network":
2507
+ return getNetworkGraphPositions(graph);
2508
+ case "spatial":
2509
+ return getSpatialGraphPositions(graph);
2510
+ case "cluster":
2511
+ default:
2512
+ return getClusterGraphPositions(graph);
2513
+ }
2754
2514
  }
2755
2515
 
2516
+ // src/hooks/operations/command-view/useCommandViewStore.ts
2517
+ var DEFAULT_DIAGNOSTIC_CATEGORIES = ["diagnostic", "testing"];
2518
+ var useCommandViewStore = create()(
2519
+ persist(
2520
+ (set) => ({
2521
+ statusFilter: "all",
2522
+ setStatusFilter: (statusFilter) => set({ statusFilter }),
2523
+ showIntegrations: true,
2524
+ setShowIntegrations: (showIntegrations) => set({ showIntegrations }),
2525
+ fitViewOnFilter: true,
2526
+ setFitViewOnFilter: (fitViewOnFilter) => set({ fitViewOnFilter }),
2527
+ visualizationMode: DEFAULT_COMMAND_VIEW_VISUALIZATION_MODE,
2528
+ setVisualizationMode: (visualizationMode) => set({ visualizationMode }),
2529
+ selectedNodeId: null,
2530
+ setSelectedNodeId: (selectedNodeId) => set({ selectedNodeId }),
2531
+ resourcesHidden: true,
2532
+ setResourcesHidden: (resourcesHidden) => set({ resourcesHidden, hasVisibilityInteraction: true }),
2533
+ diagnosticsHidden: true,
2534
+ setDiagnosticsHidden: (diagnosticsHidden) => set({ diagnosticsHidden, hasVisibilityInteraction: true }),
2535
+ diagnosticCategories: DEFAULT_DIAGNOSTIC_CATEGORIES,
2536
+ revealedIds: /* @__PURE__ */ new Set(),
2537
+ setRevealedIds: (ids) => set({ revealedIds: new Set(ids) }),
2538
+ clearRevealedIds: () => set({ revealedIds: /* @__PURE__ */ new Set() }),
2539
+ hasVisibilityInteraction: false,
2540
+ markVisibilityInteraction: () => set({ hasVisibilityInteraction: true }),
2541
+ resetVisibilityInteraction: () => set({ hasVisibilityInteraction: false })
2542
+ }),
2543
+ {
2544
+ name: "command-view-store",
2545
+ partialize: (s) => ({
2546
+ showIntegrations: s.showIntegrations,
2547
+ fitViewOnFilter: s.fitViewOnFilter,
2548
+ visualizationMode: s.visualizationMode,
2549
+ resourcesHidden: s.resourcesHidden,
2550
+ diagnosticsHidden: s.diagnosticsHidden
2551
+ })
2552
+ }
2553
+ )
2554
+ );
2555
+
2756
2556
  // src/hooks/operations/shared/queryKeys.ts
2757
2557
  var operationsKeys = {
2758
2558
  all: ["operations"],
@@ -3552,7 +3352,7 @@ var acquisitionListKeys = {
3552
3352
  detail: (organizationId, listId) => [...acquisitionListKeys.all, organizationId, listId],
3553
3353
  telemetry: (organizationId) => [...acquisitionListKeys.all, "telemetry", organizationId],
3554
3354
  progress: (organizationId, listId) => [...acquisitionListKeys.all, "progress", organizationId, listId],
3555
- executions: (organizationId, listId) => [...acquisitionListKeys.all, "executions", organizationId, listId]
3355
+ executions: (organizationId, listId, filters) => [...acquisitionListKeys.all, "executions", organizationId, listId, filters?.resourceId ?? null, filters?.limit ?? null]
3556
3356
  };
3557
3357
  function useLists() {
3558
3358
  const { apiRequest, isReady, organizationId } = useElevasisServices();
@@ -3586,11 +3386,15 @@ function useListProgress(listId) {
3586
3386
  enabled: isReady && !!listId
3587
3387
  });
3588
3388
  }
3589
- function useListExecutions(listId) {
3389
+ function useListExecutions(listId, filters = {}) {
3590
3390
  const { apiRequest, isReady, organizationId } = useElevasisServices();
3591
3391
  return useQuery({
3592
- queryKey: acquisitionListKeys.executions(organizationId, listId),
3593
- queryFn: () => apiRequest(`/acquisition/lists/${listId}/executions`),
3392
+ queryKey: acquisitionListKeys.executions(organizationId, listId, filters),
3393
+ queryFn: async () => {
3394
+ const executions = await apiRequest(`/acquisition/lists/${listId}/executions`);
3395
+ const filteredExecutions = filters.resourceId ? executions.filter((execution) => execution.resourceId === filters.resourceId) : executions;
3396
+ return typeof filters.limit === "number" ? filteredExecutions.slice(0, filters.limit) : filteredExecutions;
3397
+ },
3594
3398
  enabled: isReady && !!listId
3595
3399
  });
3596
3400
  }
@@ -4592,6 +4396,20 @@ function useDeleteRequest() {
4592
4396
  }
4593
4397
  });
4594
4398
  }
4399
+ function useResourceErrors({ resourceId, timeRange, hasFailures }) {
4400
+ const { apiRequest, organizationId, isReady } = useElevasisServices();
4401
+ return useQuery({
4402
+ queryKey: ["resource-errors", organizationId, resourceId, timeRange],
4403
+ queryFn: async () => {
4404
+ return apiRequest(
4405
+ `/command-view/resource-errors?resourceId=${resourceId}&timeRange=${timeRange}`
4406
+ );
4407
+ },
4408
+ // Only fetch when: org ready, resource selected, and resource has failures
4409
+ enabled: isReady && !!resourceId && hasFailures,
4410
+ staleTime: STALE_TIME_ADMIN
4411
+ });
4412
+ }
4595
4413
  function useDealDetail(acqDealId) {
4596
4414
  const { apiRequest, isReady, organizationId } = useElevasisServices();
4597
4415
  return useQuery({
@@ -5305,4 +5123,4 @@ function useProjectRealtime(projectId) {
5305
5123
  });
5306
5124
  }
5307
5125
 
5308
- export { ApiKeyService, COMMAND_VIEW_VISUALIZATION_MODES, CredentialSchemas, CredentialService, DeploymentService, MEMBERSHIP_STATUS_COLORS, OperationsService, OrganizationMembershipService, WebhookEndpointService, acquisitionListKeys, collectResourceFilterFacets, companyKeys, contactKeys, dealKeys, dealNoteKeys, dealTaskKeys, executionsKeys, filterByDomainFilters, getCommandViewGraphPositions, getResourceFilterFacetIds, isSessionCapable, labelResourceFilterFacet, leadGenArtifactKeys, leadGenListCompanyKeys, leadGenListMemberKeys, operationsKeys, projectActivityKeys, requestsKeys, scheduleKeys, sessionsKeys, sortData, transformMembershipToTableRow, useActivateDeployment, useActivities, useActivitiesRealtime, useActivityFilters, useActivityTrend, useAddCompaniesToList, useAddContactsToList, useArchiveSession, useArchivedLogs, useArtifacts, useAssignRole, useBatchDelete, useBatchTelemetry, useBatchedResourcesHealth, useBulkDeleteExecutions, useBusinessImpact, useCancelExecution, useCancelSchedule, useCheckpointTasks, useCommandQueue, useCommandQueueTotals, useCommandViewData, useCommandViewDomainFilters, useCommandViewLayout, useCommandViewStats, useCommandViewStore, useCompanies, useCompany, useCompanyFacets, useCompleteDealTask, useContact, useContacts, useCostBreakdown, useCostByModel, useCostSummary, useCostTrends, useCreateApiKey, useCreateArtifact, useCreateCompany, useCreateContact, useCreateCredential, useCreateDealNote, useCreateDealTask, useCreateList, useCreateOrgRole, useCreateSchedule, useCreateSession, useCreateWebhookEndpoint, useCredentials, useDashboardMetrics, useDeactivateDeployment, useDeactivateMembership, useDealDetail, useDealNotes, useDealTasks, useDealTasksDue, useDeals, useDealsLookup, useDealsSummary, useDeleteApiKey, useDeleteCompanies, useDeleteContacts, useDeleteCredential, useDeleteDeal, useDeleteDeployment, useDeleteExecution, useDeleteList, useDeleteOrgRole, useDeleteRequest, useDeleteSchedule, useDeleteSession, useDeleteTask, useDeleteWebhookEndpoint, useDeriveActions, useEffectivePermissions, useErrorAnalysis, useErrorDetail, useErrorDetails, useErrorDistribution, useErrorNotification, useExecuteAction, useExecuteAsync, useExecuteResource, useExecution, useExecutionHealth, useExecutionLogSSE, useExecutionLogs, useExecutionLogsFilters, useExecutionPanelState, useExecutionSSE, useExecutions, useGetExecutionHistory, useGetSchedule, useGraphStats, useHasPermission, useList, useListApiKeys, useListDeployments, useListExecutions, useListMember, useListMembers, useListProgress, useListSchedules, useListWebhookEndpoints, useLists, useListsTelemetry, useMarkAllAsRead, useMarkAsRead, useNotificationCount, useNotifications, useOrgRoles, useOrganizationMembers, useOrganizationPermissions, usePaginationState, usePatchTask, usePauseSchedule, usePermissionCatalog, useProjectActivities, useProjectRealtime, useReactivateMembership, useRecentExecutionsByResource, useRemoveCompaniesFromList, useRequest, useRequestsList, useResolveAllErrors, useResolveError, useResolveErrorsByExecution, useResourceDefinition, useResourceErrors, useResourceExecutions, useResourceSearch, useResources, useResourcesDomainFilters, useResourcesHealth, useResumeSchedule, useRetryExecution, useRevokeRole, useSSEConnection, useScheduledTasks, useSession, useSessionExecution, useSessionExecutions, useSessionMessages, useSessionWebSocket, useSessions, useSortedData, useStatusFilter, useSubmitAction, useSuccessNotification, useTableSelection, useTableSort, useTestNotification, useTimeRangeDates, useTopFailingResources, useTransitionItem, useTransitionListCompany, useTransitionListMember, useTransitionState, useUnresolveError, useUnresolvedErrors, useUpdateAnchor, useUpdateApiKey, useUpdateCompany, useUpdateContact, useUpdateCredential, useUpdateList, useUpdateListConfig, useUpdateListStatus, useUpdateMemberConfig, useUpdateOrgRole, useUpdateRequestStatus, useUpdateSchedule, useUpdateWebhookEndpoint, useUserMemberships, useVisibleResources, useWarningNotification, useWorkflowExecution };
5126
+ export { ApiKeyService, COMMAND_VIEW_VISUALIZATION_MODES, CredentialSchemas, CredentialService, DeploymentService, MEMBERSHIP_STATUS_COLORS, OperationsService, OrganizationMembershipService, WebhookEndpointService, acquisitionListKeys, collectResourceFilterFacets, companyKeys, contactKeys, dealKeys, dealNoteKeys, dealTaskKeys, executionsKeys, filterByDomainFilters, getCommandViewGraphPositions, getResourceFilterFacetIds, isSessionCapable, labelResourceFilterFacet, leadGenArtifactKeys, leadGenListCompanyKeys, leadGenListMemberKeys, operationsKeys, projectActivityKeys, requestsKeys, scheduleKeys, sessionsKeys, sortData, transformMembershipToTableRow, useActivateDeployment, useActivities, useActivitiesRealtime, useActivityFilters, useActivityTrend, useAddCompaniesToList, useAddContactsToList, useArchiveSession, useArchivedLogs, useArtifacts, useAssignRole, useBatchDelete, useBatchTelemetry, useBatchedResourcesHealth, useBulkDeleteExecutions, useBusinessImpact, useCancelExecution, useCancelSchedule, useCheckpointTasks, useCommandQueue, useCommandQueueTotals, useCommandViewData, useCommandViewDomainFilters, useCommandViewStats, useCommandViewStore, useCompanies, useCompany, useCompanyFacets, useCompleteDealTask, useContact, useContacts, useCostBreakdown, useCostByModel, useCostSummary, useCostTrends, useCreateApiKey, useCreateArtifact, useCreateCompany, useCreateContact, useCreateCredential, useCreateDealNote, useCreateDealTask, useCreateList, useCreateOrgRole, useCreateSchedule, useCreateSession, useCreateWebhookEndpoint, useCredentials, useDashboardMetrics, useDeactivateDeployment, useDeactivateMembership, useDealDetail, useDealNotes, useDealTasks, useDealTasksDue, useDeals, useDealsLookup, useDealsSummary, useDeleteApiKey, useDeleteCompanies, useDeleteContacts, useDeleteCredential, useDeleteDeal, useDeleteDeployment, useDeleteExecution, useDeleteList, useDeleteOrgRole, useDeleteRequest, useDeleteSchedule, useDeleteSession, useDeleteTask, useDeleteWebhookEndpoint, useDeriveActions, useEffectivePermissions, useErrorAnalysis, useErrorDetail, useErrorDetails, useErrorDistribution, useErrorNotification, useExecuteAction, useExecuteAsync, useExecuteResource, useExecution, useExecutionHealth, useExecutionLogSSE, useExecutionLogs, useExecutionLogsFilters, useExecutionPanelState, useExecutionSSE, useExecutions, useGetExecutionHistory, useGetSchedule, useHasPermission, useList, useListApiKeys, useListDeployments, useListExecutions, useListMember, useListMembers, useListProgress, useListSchedules, useListWebhookEndpoints, useLists, useListsTelemetry, useMarkAllAsRead, useMarkAsRead, useNotificationCount, useNotifications, useOrgRoles, useOrganizationMembers, useOrganizationPermissions, usePaginationState, usePatchTask, usePauseSchedule, usePermissionCatalog, useProjectActivities, useProjectRealtime, useReactivateMembership, useRecentExecutionsByResource, useRemoveCompaniesFromList, useRequest, useRequestsList, useResolveAllErrors, useResolveError, useResolveErrorsByExecution, useResourceDefinition, useResourceErrors, useResourceExecutions, useResourceSearch, useResources, useResourcesDomainFilters, useResourcesHealth, useResumeSchedule, useRetryExecution, useRevokeRole, useSSEConnection, useScheduledTasks, useSession, useSessionExecution, useSessionExecutions, useSessionMessages, useSessionWebSocket, useSessions, useSortedData, useStatusFilter, useSubmitAction, useSuccessNotification, useTableSelection, useTableSort, useTestNotification, useTimeRangeDates, useTopFailingResources, useTransitionItem, useTransitionListCompany, useTransitionListMember, useTransitionState, useUnresolveError, useUnresolvedErrors, useUpdateAnchor, useUpdateApiKey, useUpdateCompany, useUpdateContact, useUpdateCredential, useUpdateList, useUpdateListConfig, useUpdateListStatus, useUpdateMemberConfig, useUpdateOrgRole, useUpdateRequestStatus, useUpdateSchedule, useUpdateWebhookEndpoint, useUserMemberships, useVisibleResources, useWarningNotification, useWorkflowExecution };